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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -35,11 +35,11 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
=============================================================================*/
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
*----------------------------------------------------------------------------*/
#define LITTLEENDIAN 1
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
*----------------------------------------------------------------------------*/
#ifdef __GNUC_STDC_INLINE__
#define INLINE inline
#else
@ -47,8 +47,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endif
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
*----------------------------------------------------------------------------*/
#define SOFTFLOAT_BUILTIN_CLZ 1
#define SOFTFLOAT_INTRINSIC_INT128 1
#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".
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
==> #define LITTLEENDIAN 1
*----------------------------------------------------------------------------*/
== > #define LITTLEENDIAN 1
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
==> #define INLINE inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
==> #define THREAD_LOCAL _Thread_local
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
== > #define INLINE inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
== > #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".
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
==> #define LITTLEENDIAN 1
*----------------------------------------------------------------------------*/
== > #define LITTLEENDIAN 1
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
==> #define INLINE inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
==> #define THREAD_LOCAL _Thread_local
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
== > #define INLINE inline
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
== > #define THREAD_LOCAL _Thread_local

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h
#define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h"
#include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*----------------------------------------------------------------------------
| 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_fromNegOverflow 0xFFFFFFFF
#define ui32_fromNaN 0xFFFFFFFF
#define i32_fromPosOverflow (-0x7FFFFFFF - 1)
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN (-0x7FFFFFFF - 1)
#define ui32_fromNaN 0xFFFFFFFF
#define i32_fromPosOverflow (-0x7FFFFFFF - 1)
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN (-0x7FFFFFFF - 1)
/*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an
| invalid exception.
*----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define ui64_fromNegOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define i64_fromPosOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
#define i64_fromNaN (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
#define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF)
#define i64_fromPosOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
/*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format
@ -92,7 +92,7 @@ struct commonNaN {
| 16-bit floating-point signaling NaN.
| 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
@ -100,13 +100,13 @@ struct commonNaN {
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast16_t
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
/*----------------------------------------------------------------------------
| 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.
| 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
@ -135,13 +134,13 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast32_t
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
/*----------------------------------------------------------------------------
| 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
| 64-bit floating-point signaling NaN.
| 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
@ -170,13 +169,13 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast64_t
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
/*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0xFFFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 )
#define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating
@ -199,7 +197,8 @@ uint_fast64_t
| floating-point signaling NaN.
| 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
@ -215,16 +214,14 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_extF80UIToCommonNaN(
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
void 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
| floating-point NaN, and returns the bit pattern of this value as an unsigned
| 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
@ -235,19 +232,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
struct uint128 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.
*----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 )
#define defaultNaNF128UI0 UINT64_C( 0 )
#define defaultNaNF128UI64 UINT64_C(0xFFFF800000000000)
#define defaultNaNF128UI0 UINT64_C(0)
/*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating
@ -255,7 +246,8 @@ struct uint128
| point signaling NaN.
| 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'
@ -264,15 +256,13 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised.
*----------------------------------------------------------------------------*/
void
softfloat_f128UIToCommonNaN(
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
void 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
| 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
@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
#else
@ -304,18 +288,14 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_extF80MToCommonNaN(
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
/*----------------------------------------------------------------------------
| 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
| 'zSPtr'.
*----------------------------------------------------------------------------*/
void
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
/*----------------------------------------------------------------------------
| 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
| value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
void 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.
@ -336,7 +311,7 @@ void
#define defaultNaNF128UI96 0xFFFF8000
#define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0
#define defaultNaNF128UI0 0
/*----------------------------------------------------------------------------
| 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
| to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
/*----------------------------------------------------------------------------
| 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
| platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
/*----------------------------------------------------------------------------
| 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
| the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
#endif
#endif

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h
#define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h"
#include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*----------------------------------------------------------------------------
| 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_fromNegOverflow 0xFFFFFFFF
#define ui32_fromNaN 0xFFFFFFFF
#define i32_fromPosOverflow (-0x7FFFFFFF - 1)
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN (-0x7FFFFFFF - 1)
#define ui32_fromNaN 0xFFFFFFFF
#define i32_fromPosOverflow (-0x7FFFFFFF - 1)
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN (-0x7FFFFFFF - 1)
/*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an
| invalid exception.
*----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define ui64_fromNegOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define i64_fromPosOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
#define i64_fromNaN (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
#define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF)
#define i64_fromPosOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
/*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format
@ -92,7 +92,7 @@ struct commonNaN {
| 16-bit floating-point signaling NaN.
| 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
@ -100,13 +100,13 @@ struct commonNaN {
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast16_t
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
/*----------------------------------------------------------------------------
| 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.
| 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
@ -135,13 +134,13 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast32_t
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
/*----------------------------------------------------------------------------
| 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
| 64-bit floating-point signaling NaN.
| 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
@ -170,13 +169,13 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast64_t
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
/*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0xFFFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 )
#define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating
@ -199,7 +197,8 @@ uint_fast64_t
| floating-point signaling NaN.
| 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
@ -215,16 +214,14 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_extF80UIToCommonNaN(
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
void 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
| floating-point NaN, and returns the bit pattern of this value as an unsigned
| 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
@ -235,19 +232,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
struct uint128 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.
*----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 )
#define defaultNaNF128UI0 UINT64_C( 0 )
#define defaultNaNF128UI64 UINT64_C(0xFFFF800000000000)
#define defaultNaNF128UI0 UINT64_C(0)
/*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating
@ -255,7 +246,8 @@ struct uint128
| point signaling NaN.
| 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'
@ -264,15 +256,13 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised.
*----------------------------------------------------------------------------*/
void
softfloat_f128UIToCommonNaN(
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
void 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
| 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
@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
#else
@ -304,18 +288,14 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_extF80MToCommonNaN(
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
/*----------------------------------------------------------------------------
| 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
| 'zSPtr'.
*----------------------------------------------------------------------------*/
void
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
/*----------------------------------------------------------------------------
| 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
| value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
void 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.
@ -336,7 +311,7 @@ void
#define defaultNaNF128UI96 0xFFFF8000
#define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0
#define defaultNaNF128UI0 0
/*----------------------------------------------------------------------------
| 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
| to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
/*----------------------------------------------------------------------------
| 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
| platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
/*----------------------------------------------------------------------------
| 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
| the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
#endif
#endif

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h
#define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h"
#include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*----------------------------------------------------------------------------
| 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_fromNegOverflow 0
#define ui32_fromNaN 0
#define i32_fromPosOverflow 0x7FFFFFFF
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN 0
#define ui32_fromNaN 0
#define i32_fromPosOverflow 0x7FFFFFFF
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN 0
/*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an
| invalid exception.
*----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow 0
#define ui64_fromNaN 0
#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF )
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
#define i64_fromNaN 0
#define ui64_fromNaN 0
#define i64_fromPosOverflow INT64_C(0x7FFFFFFFFFFFFFFF)
#define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN 0
/*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format
| to another.
*----------------------------------------------------------------------------*/
struct commonNaN { char _unused; };
struct commonNaN {
char _unused;
};
/*----------------------------------------------------------------------------
| 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.
| 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
@ -93,13 +95,15 @@ struct commonNaN { char _unused; };
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -107,8 +111,7 @@ struct commonNaN { char _unused; };
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast16_t
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
/*----------------------------------------------------------------------------
| 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.
| 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
@ -128,13 +131,15 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -142,20 +147,20 @@ uint_fast16_t
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast32_t
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
/*----------------------------------------------------------------------------
| 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
| 64-bit floating-point signaling NaN.
| 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
@ -163,13 +168,15 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -177,14 +184,13 @@ uint_fast32_t
| the combined NaN result. If either 'uiA' or 'uiB' has the pattern of a
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast64_t
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
/*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0x7FFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 )
#define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating
@ -192,7 +198,8 @@ uint_fast64_t
| floating-point signaling NaN.
| 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
@ -208,24 +215,25 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| floating-point NaN, and returns the bit pattern of this value as an unsigned
| integer.
*----------------------------------------------------------------------------*/
#if defined INLINE && ! defined softfloat_commonNaNToExtF80UI
#if defined INLINE && !defined softfloat_commonNaNToExtF80UI
INLINE
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr )
{
struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr) {
struct uint128 uiZ;
uiZ.v64 = defaultNaNExtF80UI64;
uiZ.v0 = defaultNaNExtF80UI0;
uiZ.v0 = defaultNaNExtF80UI0;
return uiZ;
}
#else
struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
struct uint128 softfloat_commonNaNToExtF80UI(const struct commonNaN* aPtr);
#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
| invalid exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
struct uint128 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.
*----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0x7FFF800000000000 )
#define defaultNaNF128UI0 UINT64_C( 0 )
#define defaultNaNF128UI64 UINT64_C(0x7FFF800000000000)
#define defaultNaNF128UI0 UINT64_C(0)
/*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating
@ -257,7 +259,8 @@ struct uint128
| point signaling NaN.
| 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'
@ -266,23 +269,24 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| 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
| 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
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN *aPtr )
{
struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN* aPtr) {
struct uint128 uiZ;
uiZ.v64 = defaultNaNF128UI64;
uiZ.v0 = defaultNaNF128UI0;
uiZ.v0 = defaultNaNF128UI0;
return uiZ;
}
#else
struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
struct uint128 softfloat_commonNaNToF128UI(const struct commonNaN*);
#endif
/*----------------------------------------------------------------------------
@ -294,13 +298,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
#else
@ -315,26 +313,23 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| 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
| floating-point NaN, and stores this NaN at the location pointed to by
| 'zSPtr'.
*----------------------------------------------------------------------------*/
#if defined INLINE && ! defined softfloat_commonNaNToExtF80M
#if defined INLINE && !defined softfloat_commonNaNToExtF80M
INLINE
void
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr )
{
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr) {
zSPtr->signExp = defaultNaNExtF80UI64;
zSPtr->signif = defaultNaNExtF80UI0;
zSPtr->signif = defaultNaNExtF80UI0;
}
#else
void
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
#endif
/*----------------------------------------------------------------------------
@ -343,12 +338,7 @@ void
| at the location pointed to by 'zSPtr'. If either original floating-point
| value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
void 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.
@ -356,7 +346,7 @@ void
#define defaultNaNF128UI96 0x7FFF8000
#define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0
#define defaultNaNF128UI0 0
/*----------------------------------------------------------------------------
| 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
| 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
@ -374,19 +366,16 @@ void
| '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.
*----------------------------------------------------------------------------*/
#if defined INLINE && ! defined softfloat_commonNaNToF128M
#if defined INLINE && !defined softfloat_commonNaNToF128M
INLINE
void
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr )
{
zWPtr[indexWord( 4, 3 )] = defaultNaNF128UI96;
zWPtr[indexWord( 4, 2 )] = defaultNaNF128UI64;
zWPtr[indexWord( 4, 1 )] = defaultNaNF128UI32;
zWPtr[indexWord( 4, 0 )] = defaultNaNF128UI0;
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr) {
zWPtr[indexWord(4, 3)] = defaultNaNF128UI96;
zWPtr[indexWord(4, 2)] = defaultNaNF128UI64;
zWPtr[indexWord(4, 1)] = defaultNaNF128UI32;
zWPtr[indexWord(4, 0)] = defaultNaNF128UI0;
}
#else
void
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
#endif
/*----------------------------------------------------------------------------
@ -397,11 +386,8 @@ void
| 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.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
#endif
#endif

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h
#define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h"
#include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*----------------------------------------------------------------------------
| 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_fromNegOverflow 0
#define ui32_fromNaN 0
#define i32_fromPosOverflow 0x7FFFFFFF
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN 0
#define ui32_fromNaN 0
#define i32_fromPosOverflow 0x7FFFFFFF
#define i32_fromNegOverflow (-0x7FFFFFFF - 1)
#define i32_fromNaN 0
/*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an
| invalid exception.
*----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow 0
#define ui64_fromNaN 0
#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF )
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF ) - 1)
#define i64_fromNaN 0
#define ui64_fromNaN 0
#define i64_fromPosOverflow INT64_C(0x7FFFFFFFFFFFFFFF)
#define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN 0
/*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format
@ -92,7 +92,7 @@ struct commonNaN {
| 16-bit floating-point signaling NaN.
| 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
@ -100,13 +100,13 @@ struct commonNaN {
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast16_t
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
/*----------------------------------------------------------------------------
| 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.
| 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
@ -135,13 +134,13 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast32_t
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
/*----------------------------------------------------------------------------
| 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
| 64-bit floating-point signaling NaN.
| 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
@ -170,13 +169,13 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast64_t
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
/*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0x7FFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 )
#define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating
@ -199,7 +197,8 @@ uint_fast64_t
| floating-point signaling NaN.
| 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
@ -215,16 +214,14 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_extF80UIToCommonNaN(
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
void 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
| floating-point NaN, and returns the bit pattern of this value as an unsigned
| 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
@ -235,19 +232,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
struct uint128 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.
*----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0x7FFF800000000000 )
#define defaultNaNF128UI0 UINT64_C( 0 )
#define defaultNaNF128UI64 UINT64_C(0x7FFF800000000000)
#define defaultNaNF128UI0 UINT64_C(0)
/*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating
@ -255,7 +246,8 @@ struct uint128
| point signaling NaN.
| 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'
@ -264,15 +256,13 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised.
*----------------------------------------------------------------------------*/
void
softfloat_f128UIToCommonNaN(
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
void 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
| 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
@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
#else
@ -304,18 +288,14 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_extF80MToCommonNaN(
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
/*----------------------------------------------------------------------------
| 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
| 'zSPtr'.
*----------------------------------------------------------------------------*/
void
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
/*----------------------------------------------------------------------------
| 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
| value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
void 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.
@ -336,7 +311,7 @@ void
#define defaultNaNF128UI96 0x7FFF8000
#define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0
#define defaultNaNF128UI0 0
/*----------------------------------------------------------------------------
| 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
| to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
/*----------------------------------------------------------------------------
| 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
| platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
/*----------------------------------------------------------------------------
| 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
| the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
#endif
#endif

View File

@ -37,10 +37,10 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef specialize_h
#define specialize_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitiveTypes.h"
#include "softfloat.h"
#include <stdbool.h>
#include <stdint.h>
/*----------------------------------------------------------------------------
| 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_fromNegOverflow UINT32_C(0x0)
#define ui32_fromNaN UINT32_C(0xFFFFFFFF)
#define i32_fromPosOverflow INT64_C(0x7FFFFFFF)
#define i32_fromNegOverflow (-INT64_C(0x7FFFFFFF)-1)
#define i32_fromNaN INT64_C(0x7FFFFFFF)
#define ui32_fromNaN UINT32_C(0xFFFFFFFF)
#define i32_fromPosOverflow INT64_C(0x7FFFFFFF)
#define i32_fromNegOverflow (-INT64_C(0x7FFFFFFF) - 1)
#define i32_fromNaN INT64_C(0x7FFFFFFF)
/*----------------------------------------------------------------------------
| The values to return on conversions to 64-bit integer formats that raise an
| invalid exception.
*----------------------------------------------------------------------------*/
#define ui64_fromPosOverflow UINT64_C( 0xFFFFFFFFFFFFFFFF )
#define ui64_fromNegOverflow UINT64_C( 0x0 )
#define ui64_fromNaN UINT64_C( 0xFFFFFFFFFFFFFFFF)
#define i64_fromPosOverflow INT64_C( 0x7FFFFFFFFFFFFFFF)
#define i64_fromNegOverflow (-INT64_C( 0x7FFFFFFFFFFFFFFF)-1)
#define i64_fromNaN INT64_C( 0x7FFFFFFFFFFFFFFF)
#define ui64_fromPosOverflow UINT64_C(0xFFFFFFFFFFFFFFFF)
#define ui64_fromNegOverflow UINT64_C(0x0)
#define ui64_fromNaN UINT64_C(0xFFFFFFFFFFFFFFFF)
#define i64_fromPosOverflow INT64_C(0x7FFFFFFFFFFFFFFF)
#define i64_fromNegOverflow (-INT64_C(0x7FFFFFFFFFFFFFFF) - 1)
#define i64_fromNaN INT64_C(0x7FFFFFFFFFFFFFFF)
/*----------------------------------------------------------------------------
| "Common NaN" structure, used to transfer NaN representations from one format
@ -92,7 +92,7 @@ struct commonNaN {
| 16-bit floating-point signaling NaN.
| 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
@ -100,13 +100,13 @@ struct commonNaN {
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast16_t
softfloat_propagateNaNF16UI( uint_fast16_t uiA, uint_fast16_t uiB );
uint_fast16_t softfloat_propagateNaNF16UI(uint_fast16_t uiA, uint_fast16_t uiB);
/*----------------------------------------------------------------------------
| 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.
| 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
@ -135,13 +134,13 @@ uint_fast16_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast32_t
softfloat_propagateNaNF32UI( uint_fast32_t uiA, uint_fast32_t uiB );
uint_fast32_t softfloat_propagateNaNF32UI(uint_fast32_t uiA, uint_fast32_t uiB);
/*----------------------------------------------------------------------------
| 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
| 64-bit floating-point signaling NaN.
| 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
@ -170,13 +169,13 @@ uint_fast32_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| 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
| 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-
@ -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
| signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
uint_fast64_t
softfloat_propagateNaNF64UI( uint_fast64_t uiA, uint_fast64_t uiB );
uint_fast64_t softfloat_propagateNaNF64UI(uint_fast64_t uiA, uint_fast64_t uiB);
/*----------------------------------------------------------------------------
| The bit pattern for a default generated 80-bit extended floating-point NaN.
*----------------------------------------------------------------------------*/
#define defaultNaNExtF80UI64 0xFFFF
#define defaultNaNExtF80UI0 UINT64_C( 0xC000000000000000 )
#define defaultNaNExtF80UI0 UINT64_C(0xC000000000000000)
/*----------------------------------------------------------------------------
| Returns true when the 80-bit unsigned integer formed from concatenating
@ -199,7 +197,8 @@ uint_fast64_t
| floating-point signaling NaN.
| 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
@ -215,16 +214,14 @@ uint_fast64_t
| location pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_extF80UIToCommonNaN(
uint_fast16_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
void 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
| floating-point NaN, and returns the bit pattern of this value as an unsigned
| 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
@ -235,19 +232,13 @@ struct uint128 softfloat_commonNaNToExtF80UI( const struct commonNaN *aPtr );
| result. If either original floating-point value is a signaling NaN, the
| invalid exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNExtF80UI(
uint_fast16_t uiA64,
uint_fast64_t uiA0,
uint_fast16_t uiB64,
uint_fast64_t uiB0
);
struct uint128 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.
*----------------------------------------------------------------------------*/
#define defaultNaNF128UI64 UINT64_C( 0xFFFF800000000000 )
#define defaultNaNF128UI0 UINT64_C( 0 )
#define defaultNaNF128UI64 UINT64_C(0xFFFF800000000000)
#define defaultNaNF128UI0 UINT64_C(0)
/*----------------------------------------------------------------------------
| Returns true when the 128-bit unsigned integer formed from concatenating
@ -255,7 +246,8 @@ struct uint128
| point signaling NaN.
| 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'
@ -264,15 +256,13 @@ struct uint128
| pointed to by 'zPtr'. If the NaN is a signaling NaN, the invalid exception
| is raised.
*----------------------------------------------------------------------------*/
void
softfloat_f128UIToCommonNaN(
uint_fast64_t uiA64, uint_fast64_t uiA0, struct commonNaN *zPtr );
void 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
| 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
@ -283,13 +273,7 @@ struct uint128 softfloat_commonNaNToF128UI( const struct commonNaN * );
| If either original floating-point value is a signaling NaN, the invalid
| exception is raised.
*----------------------------------------------------------------------------*/
struct uint128
softfloat_propagateNaNF128UI(
uint_fast64_t uiA64,
uint_fast64_t uiA0,
uint_fast64_t uiB64,
uint_fast64_t uiB0
);
struct uint128 softfloat_propagateNaNF128UI(uint_fast64_t uiA64, uint_fast64_t uiA0, uint_fast64_t uiB64, uint_fast64_t uiB0);
#else
@ -304,18 +288,14 @@ struct uint128
| common NaN at the location pointed to by 'zPtr'. If the NaN is a signaling
| NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_extF80MToCommonNaN(
const struct extFloat80M *aSPtr, struct commonNaN *zPtr );
void softfloat_extF80MToCommonNaN(const struct extFloat80M* aSPtr, struct commonNaN* zPtr);
/*----------------------------------------------------------------------------
| 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
| 'zSPtr'.
*----------------------------------------------------------------------------*/
void
softfloat_commonNaNToExtF80M(
const struct commonNaN *aPtr, struct extFloat80M *zSPtr );
void softfloat_commonNaNToExtF80M(const struct commonNaN* aPtr, struct extFloat80M* zSPtr);
/*----------------------------------------------------------------------------
| 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
| value is a signaling NaN, the invalid exception is raised.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNExtF80M(
const struct extFloat80M *aSPtr,
const struct extFloat80M *bSPtr,
struct extFloat80M *zSPtr
);
void 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.
@ -336,7 +311,7 @@ void
#define defaultNaNF128UI96 0xFFFF8000
#define defaultNaNF128UI64 0
#define defaultNaNF128UI32 0
#define defaultNaNF128UI0 0
#define defaultNaNF128UI0 0
/*----------------------------------------------------------------------------
| 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
| to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_f128MToCommonNaN( const uint32_t *aWPtr, struct commonNaN *zPtr );
void softfloat_f128MToCommonNaN(const uint32_t* aWPtr, struct commonNaN* zPtr);
/*----------------------------------------------------------------------------
| 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
| platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_commonNaNToF128M( const struct commonNaN *aPtr, uint32_t *zWPtr );
void softfloat_commonNaNToF128M(const struct commonNaN* aPtr, uint32_t* zWPtr);
/*----------------------------------------------------------------------------
| 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
| the platform's normal endian order to form a 128-bit floating-point value.
*----------------------------------------------------------------------------*/
void
softfloat_propagateNaNF128M(
const uint32_t *aWPtr, const uint32_t *bWPtr, uint32_t *zWPtr );
void softfloat_propagateNaNF128M(const uint32_t* aWPtr, const uint32_t* bWPtr, uint32_t* zWPtr);
#endif
#endif

View File

@ -37,242 +37,205 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef internals_h
#define internals_h 1
#include <stdbool.h>
#include <stdint.h>
#include "primitives.h"
#include "softfloat_types.h"
#include <stdbool.h>
#include <stdint.h>
union ui16_f16 { uint16_t ui; float16_t f; };
union ui32_f32 { uint32_t ui; float32_t f; };
union ui64_f64 { uint64_t ui; float64_t f; };
#ifdef SOFTFLOAT_FAST_INT64
union extF80M_extF80 { struct extFloat80M fM; extFloat80_t f; };
union ui128_f128 { struct uint128 ui; float128_t f; };
#endif
enum {
softfloat_mulAdd_subC = 1,
softfloat_mulAdd_subProd = 2
union ui16_f16 {
uint16_t ui;
float16_t f;
};
union ui32_f32 {
uint32_t ui;
float32_t f;
};
union ui64_f64 {
uint64_t ui;
float64_t f;
};
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
uint_fast32_t softfloat_roundToUI32( bool, uint_fast64_t, uint_fast8_t, bool );
#ifdef SOFTFLOAT_FAST_INT64
uint_fast64_t
softfloat_roundToUI64(
bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool );
#else
uint_fast64_t softfloat_roundMToUI64( bool, uint32_t *, uint_fast8_t, bool );
union extF80M_extF80 {
struct extFloat80M fM;
extFloat80_t f;
};
union ui128_f128 {
struct uint128 ui;
float128_t f;
};
#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
int_fast64_t
softfloat_roundToI64(
bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool );
uint_fast64_t softfloat_roundToUI64(bool, uint_fast64_t, uint_fast64_t, uint_fast8_t, bool);
#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
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
#define signF16UI( a ) ((bool) ((uint16_t) (a)>>15))
#define expF16UI( a ) ((int_fast8_t) ((a)>>10) & 0x1F)
#define fracF16UI( a ) ((a) & 0x03FF)
#define packToF16UI( sign, exp, sig ) (((uint16_t) (sign)<<15) + ((uint16_t) (exp)<<10) + (sig))
*----------------------------------------------------------------------------*/
#define signF16UI(a) ((bool)((uint16_t)(a) >> 15))
#define expF16UI(a) ((int_fast8_t)((a) >> 10) & 0x1F)
#define fracF16UI(a) ((a)&0x03FF)
#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 softfloat_normSubnormalF16Sig( uint_fast16_t );
struct exp8_sig16 {
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_normRoundPackToF16( 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_addMagsF16( uint_fast16_t, uint_fast16_t );
float16_t softfloat_subMagsF16( uint_fast16_t, uint_fast16_t );
float16_t
softfloat_mulAddF16(
uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t );
float16_t softfloat_addMagsF16(uint_fast16_t, uint_fast16_t);
float16_t softfloat_subMagsF16(uint_fast16_t, uint_fast16_t);
float16_t softfloat_mulAddF16(uint_fast16_t, uint_fast16_t, uint_fast16_t, uint_fast8_t);
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
#define signF32UI( a ) ((bool) ((uint32_t) (a)>>31))
#define expF32UI( a ) ((int_fast16_t) ((a)>>23) & 0xFF)
#define fracF32UI( a ) ((a) & 0x007FFFFF)
#define packToF32UI( sign, exp, sig ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<23) + (sig))
*----------------------------------------------------------------------------*/
#define signF32UI(a) ((bool)((uint32_t)(a) >> 31))
#define expF32UI(a) ((int_fast16_t)((a) >> 23) & 0xFF)
#define fracF32UI(a) ((a)&0x007FFFFF)
#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 softfloat_normSubnormalF32Sig( uint_fast32_t );
struct exp16_sig32 {
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_normRoundPackToF32( 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_addMagsF32( uint_fast32_t, uint_fast32_t );
float32_t softfloat_subMagsF32( uint_fast32_t, uint_fast32_t );
float32_t
softfloat_mulAddF32(
uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t );
float32_t softfloat_addMagsF32(uint_fast32_t, uint_fast32_t);
float32_t softfloat_subMagsF32(uint_fast32_t, uint_fast32_t);
float32_t softfloat_mulAddF32(uint_fast32_t, uint_fast32_t, uint_fast32_t, uint_fast8_t);
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
#define signF64UI( a ) ((bool) ((uint64_t) (a)>>63))
#define expF64UI( a ) ((int_fast16_t) ((a)>>52) & 0x7FF)
#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 signF64UI(a) ((bool)((uint64_t)(a) >> 63))
#define expF64UI(a) ((int_fast16_t)((a) >> 52) & 0x7FF)
#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 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 softfloat_normSubnormalF64Sig( uint_fast64_t );
struct exp16_sig64 {
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_normRoundPackToF64( 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_addMagsF64( uint_fast64_t, uint_fast64_t, bool );
float64_t softfloat_subMagsF64( uint_fast64_t, uint_fast64_t, bool );
float64_t
softfloat_mulAddF64(
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t );
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_mulAddF64(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast8_t);
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
#define signExtF80UI64( a64 ) ((bool) ((uint16_t) (a64)>>15))
#define expExtF80UI64( a64 ) ((a64) & 0x7FFF)
#define packToExtF80UI64( sign, exp ) ((uint_fast16_t) (sign)<<15 | (exp))
*----------------------------------------------------------------------------*/
#define signExtF80UI64(a64) ((bool)((uint16_t)(a64) >> 15))
#define expExtF80UI64(a64) ((a64)&0x7FFF)
#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
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
*----------------------------------------------------------------------------*/
struct exp32_sig64 { int_fast32_t exp; uint64_t sig; };
struct exp32_sig64 softfloat_normSubnormalExtF80Sig( uint_fast64_t );
struct exp32_sig64 {
int_fast32_t exp;
uint64_t sig;
};
struct exp32_sig64 softfloat_normSubnormalExtF80Sig(uint_fast64_t);
extFloat80_t
softfloat_roundPackToExtF80(
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 softfloat_roundPackToExtF80(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
softfloat_addMagsExtF80(
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 );
extFloat80_t softfloat_addMagsExtF80(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 expF128UI64( a64 ) ((int_fast32_t) ((a64)>>48) & 0x7FFF)
#define fracF128UI64( a64 ) ((a64) & UINT64_C( 0x0000FFFFFFFFFFFF ))
#define packToF128UI64( sign, exp, sig64 ) (((uint_fast64_t) (sign)<<63) + ((uint_fast64_t) (exp)<<48) + (sig64))
*----------------------------------------------------------------------------*/
#define signF128UI64(a64) ((bool)((uint64_t)(a64) >> 63))
#define expF128UI64(a64) ((int_fast32_t)((a64) >> 48) & 0x7FFF)
#define fracF128UI64(a64) ((a64)&UINT64_C(0x0000FFFFFFFFFFFF))
#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
softfloat_normSubnormalF128Sig( uint_fast64_t, uint_fast64_t );
struct exp32_sig128 {
int_fast32_t exp;
struct uint128 sig;
};
struct exp32_sig128 softfloat_normSubnormalF128Sig(uint_fast64_t, uint_fast64_t);
float128_t
softfloat_roundPackToF128(
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 softfloat_roundPackToF128(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
softfloat_addMagsF128(
uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool );
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
);
float128_t softfloat_addMagsF128(uint_fast64_t, uint_fast64_t, uint_fast64_t, uint_fast64_t, bool);
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
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
*----------------------------------------------------------------------------*/
bool
softfloat_tryPropagateNaNExtF80M(
const struct extFloat80M *,
const struct extFloat80M *,
struct extFloat80M *
);
void softfloat_invalidExtF80M( struct extFloat80M * );
bool softfloat_tryPropagateNaNExtF80M(const struct extFloat80M*, const struct extFloat80M*, struct extFloat80M*);
void softfloat_invalidExtF80M(struct extFloat80M*);
int softfloat_normExtF80SigM( uint64_t * );
int softfloat_normExtF80SigM(uint64_t*);
void
softfloat_roundPackMToExtF80M(
bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );
void
softfloat_normRoundPackMToExtF80M(
bool, int32_t, uint32_t *, uint_fast8_t, struct extFloat80M * );
void softfloat_roundPackMToExtF80M(bool, int32_t, uint32_t*, uint_fast8_t, struct extFloat80M*);
void softfloat_normRoundPackMToExtF80M(bool, int32_t, uint32_t*, uint_fast8_t, struct extFloat80M*);
void
softfloat_addExtF80M(
const struct extFloat80M *,
const struct extFloat80M *,
struct extFloat80M *,
bool
);
void softfloat_addExtF80M(const struct extFloat80M*, const struct extFloat80M*, struct extFloat80M*, bool);
int
softfloat_compareNonnormExtF80M(
const struct extFloat80M *, const struct extFloat80M * );
int softfloat_compareNonnormExtF80M(const struct extFloat80M*, const struct extFloat80M*);
/*----------------------------------------------------------------------------
*----------------------------------------------------------------------------*/
#define signF128UI96( a96 ) ((bool) ((uint32_t) (a96)>>31))
#define expF128UI96( a96 ) ((int32_t) ((a96)>>16) & 0x7FFF)
#define fracF128UI96( a96 ) ((a96) & 0x0000FFFF)
#define packToF128UI96( sign, exp, sig96 ) (((uint32_t) (sign)<<31) + ((uint32_t) (exp)<<16) + (sig96))
*----------------------------------------------------------------------------*/
#define signF128UI96(a96) ((bool)((uint32_t)(a96) >> 31))
#define expF128UI96(a96) ((int32_t)((a96) >> 16) & 0x7FFF)
#define fracF128UI96(a96) ((a96)&0x0000FFFF)
#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
softfloat_tryPropagateNaNF128M(
const uint32_t *, const uint32_t *, uint32_t * );
void softfloat_invalidF128M( uint32_t * );
bool softfloat_tryPropagateNaNF128M(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_normRoundPackMToF128M( 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_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_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);
#endif
#endif

View File

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

View File

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

View File

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

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
| 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.
*============================================================================*/
#ifndef softfloat_h
#define softfloat_h 1
#include "softfloat_types.h"
#include <stdbool.h>
#include <stdint.h>
#include "softfloat_types.h"
#ifndef 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.
*----------------------------------------------------------------------------*/
extern THREAD_LOCAL uint_fast8_t softfloat_detectTininess;
enum {
softfloat_tininess_beforeRounding = 0,
softfloat_tininess_afterRounding = 1
};
enum { softfloat_tininess_beforeRounding = 0, softfloat_tininess_afterRounding = 1 };
/*----------------------------------------------------------------------------
| Software floating-point rounding mode. (Mode "odd" is supported only if
@ -69,12 +64,12 @@ enum {
*----------------------------------------------------------------------------*/
extern THREAD_LOCAL uint_fast8_t softfloat_roundingMode;
enum {
softfloat_round_near_even = 0,
softfloat_round_minMag = 1,
softfloat_round_min = 2,
softfloat_round_max = 3,
softfloat_round_near_even = 0,
softfloat_round_minMag = 1,
softfloat_round_min = 2,
softfloat_round_max = 3,
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;
enum {
softfloat_flag_inexact = 1,
softfloat_flag_underflow = 2,
softfloat_flag_overflow = 4,
softfloat_flag_infinite = 8,
softfloat_flag_invalid = 16
softfloat_flag_inexact = 1,
softfloat_flag_underflow = 2,
softfloat_flag_overflow = 4,
softfloat_flag_infinite = 8,
softfloat_flag_invalid = 16
};
/*----------------------------------------------------------------------------
| 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.
*----------------------------------------------------------------------------*/
float16_t ui32_to_f16( uint32_t );
float32_t ui32_to_f32( uint32_t );
float64_t ui32_to_f64( uint32_t );
float16_t ui32_to_f16(uint32_t);
float32_t ui32_to_f32(uint32_t);
float64_t ui32_to_f64(uint32_t);
#ifdef SOFTFLOAT_FAST_INT64
extFloat80_t ui32_to_extF80( uint32_t );
float128_t ui32_to_f128( uint32_t );
extFloat80_t ui32_to_extF80(uint32_t);
float128_t ui32_to_f128(uint32_t);
#endif
void ui32_to_extF80M( uint32_t, extFloat80_t * );
void ui32_to_f128M( uint32_t, float128_t * );
float16_t ui64_to_f16( uint64_t );
float32_t ui64_to_f32( uint64_t );
float64_t ui64_to_f64( uint64_t );
void ui32_to_extF80M(uint32_t, extFloat80_t*);
void ui32_to_f128M(uint32_t, float128_t*);
float16_t ui64_to_f16(uint64_t);
float32_t ui64_to_f32(uint64_t);
float64_t ui64_to_f64(uint64_t);
#ifdef SOFTFLOAT_FAST_INT64
extFloat80_t ui64_to_extF80( uint64_t );
float128_t ui64_to_f128( uint64_t );
extFloat80_t ui64_to_extF80(uint64_t);
float128_t ui64_to_f128(uint64_t);
#endif
void ui64_to_extF80M( uint64_t, extFloat80_t * );
void ui64_to_f128M( uint64_t, float128_t * );
float16_t i32_to_f16( int32_t );
float32_t i32_to_f32( int32_t );
float64_t i32_to_f64( int32_t );
void ui64_to_extF80M(uint64_t, extFloat80_t*);
void ui64_to_f128M(uint64_t, float128_t*);
float16_t i32_to_f16(int32_t);
float32_t i32_to_f32(int32_t);
float64_t i32_to_f64(int32_t);
#ifdef SOFTFLOAT_FAST_INT64
extFloat80_t i32_to_extF80( int32_t );
float128_t i32_to_f128( int32_t );
extFloat80_t i32_to_extF80(int32_t);
float128_t i32_to_f128(int32_t);
#endif
void i32_to_extF80M( int32_t, extFloat80_t * );
void i32_to_f128M( int32_t, float128_t * );
float16_t i64_to_f16( int64_t );
float32_t i64_to_f32( int64_t );
float64_t i64_to_f64( int64_t );
void i32_to_extF80M(int32_t, extFloat80_t*);
void i32_to_f128M(int32_t, float128_t*);
float16_t i64_to_f16(int64_t);
float32_t i64_to_f32(int64_t);
float64_t i64_to_f64(int64_t);
#ifdef SOFTFLOAT_FAST_INT64
extFloat80_t i64_to_extF80( int64_t );
float128_t i64_to_f128( int64_t );
extFloat80_t i64_to_extF80(int64_t);
float128_t i64_to_f128(int64_t);
#endif
void i64_to_extF80M( int64_t, extFloat80_t * );
void i64_to_f128M( int64_t, float128_t * );
void i64_to_extF80M(int64_t, extFloat80_t*);
void i64_to_f128M(int64_t, float128_t*);
/*----------------------------------------------------------------------------
| 16-bit (half-precision) floating-point operations.
*----------------------------------------------------------------------------*/
uint_fast32_t f16_to_ui32( 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_fast64_t f16_to_i64( float16_t, uint_fast8_t, bool );
uint_fast32_t f16_to_ui32_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_fast64_t f16_to_i64_r_minMag( float16_t, bool );
float32_t f16_to_f32( float16_t );
float64_t f16_to_f64( float16_t );
uint_fast32_t f16_to_ui32(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_fast64_t f16_to_i64(float16_t, uint_fast8_t, bool);
uint_fast32_t f16_to_ui32_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_fast64_t f16_to_i64_r_minMag(float16_t, bool);
float32_t f16_to_f32(float16_t);
float64_t f16_to_f64(float16_t);
#ifdef SOFTFLOAT_FAST_INT64
extFloat80_t f16_to_extF80( float16_t );
float128_t f16_to_f128( float16_t );
extFloat80_t f16_to_extF80(float16_t);
float128_t f16_to_f128(float16_t);
#endif
void f16_to_extF80M( float16_t, extFloat80_t * );
void f16_to_f128M( float16_t, float128_t * );
float16_t f16_roundToInt( float16_t, uint_fast8_t, bool );
float16_t f16_add( float16_t, float16_t );
float16_t f16_sub( 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_div( float16_t, float16_t );
float16_t f16_rem( float16_t, float16_t );
float16_t f16_sqrt( float16_t );
bool f16_eq( float16_t, float16_t );
bool f16_le( float16_t, float16_t );
bool f16_lt( float16_t, float16_t );
bool f16_eq_signaling( float16_t, float16_t );
bool f16_le_quiet( float16_t, float16_t );
bool f16_lt_quiet( float16_t, float16_t );
bool f16_isSignalingNaN( float16_t );
void f16_to_extF80M(float16_t, extFloat80_t*);
void f16_to_f128M(float16_t, float128_t*);
float16_t f16_roundToInt(float16_t, uint_fast8_t, bool);
float16_t f16_add(float16_t, float16_t);
float16_t f16_sub(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_div(float16_t, float16_t);
float16_t f16_rem(float16_t, float16_t);
float16_t f16_sqrt(float16_t);
bool f16_eq(float16_t, float16_t);
bool f16_le(float16_t, float16_t);
bool f16_lt(float16_t, float16_t);
bool f16_eq_signaling(float16_t, float16_t);
bool f16_le_quiet(float16_t, float16_t);
bool f16_lt_quiet(float16_t, float16_t);
bool f16_isSignalingNaN(float16_t);
/*----------------------------------------------------------------------------
| 32-bit (single-precision) floating-point operations.
*----------------------------------------------------------------------------*/
uint_fast32_t f32_to_ui32( 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_fast64_t f32_to_i64( float32_t, uint_fast8_t, bool );
uint_fast32_t f32_to_ui32_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_fast64_t f32_to_i64_r_minMag( float32_t, bool );
float16_t f32_to_f16( float32_t );
float64_t f32_to_f64( float32_t );
uint_fast32_t f32_to_ui32(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_fast64_t f32_to_i64(float32_t, uint_fast8_t, bool);
uint_fast32_t f32_to_ui32_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_fast64_t f32_to_i64_r_minMag(float32_t, bool);
float16_t f32_to_f16(float32_t);
float64_t f32_to_f64(float32_t);
#ifdef SOFTFLOAT_FAST_INT64
extFloat80_t f32_to_extF80( float32_t );
float128_t f32_to_f128( float32_t );
extFloat80_t f32_to_extF80(float32_t);
float128_t f32_to_f128(float32_t);
#endif
void f32_to_extF80M( float32_t, extFloat80_t * );
void f32_to_f128M( float32_t, float128_t * );
float32_t f32_roundToInt( float32_t, uint_fast8_t, bool );
float32_t f32_add( float32_t, float32_t );
float32_t f32_sub( 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_div( float32_t, float32_t );
float32_t f32_rem( float32_t, float32_t );
float32_t f32_sqrt( float32_t );
bool f32_eq( float32_t, float32_t );
bool f32_le( float32_t, float32_t );
bool f32_lt( float32_t, float32_t );
bool f32_eq_signaling( float32_t, float32_t );
bool f32_le_quiet( float32_t, float32_t );
bool f32_lt_quiet( float32_t, float32_t );
bool f32_isSignalingNaN( float32_t );
void f32_to_extF80M(float32_t, extFloat80_t*);
void f32_to_f128M(float32_t, float128_t*);
float32_t f32_roundToInt(float32_t, uint_fast8_t, bool);
float32_t f32_add(float32_t, float32_t);
float32_t f32_sub(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_div(float32_t, float32_t);
float32_t f32_rem(float32_t, float32_t);
float32_t f32_sqrt(float32_t);
bool f32_eq(float32_t, float32_t);
bool f32_le(float32_t, float32_t);
bool f32_lt(float32_t, float32_t);
bool f32_eq_signaling(float32_t, float32_t);
bool f32_le_quiet(float32_t, float32_t);
bool f32_lt_quiet(float32_t, float32_t);
bool f32_isSignalingNaN(float32_t);
/*----------------------------------------------------------------------------
| 64-bit (double-precision) floating-point operations.
*----------------------------------------------------------------------------*/
uint_fast32_t f64_to_ui32( 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_fast64_t f64_to_i64( float64_t, uint_fast8_t, bool );
uint_fast32_t f64_to_ui32_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_fast64_t f64_to_i64_r_minMag( float64_t, bool );
float16_t f64_to_f16( float64_t );
float32_t f64_to_f32( float64_t );
uint_fast32_t f64_to_ui32(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_fast64_t f64_to_i64(float64_t, uint_fast8_t, bool);
uint_fast32_t f64_to_ui32_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_fast64_t f64_to_i64_r_minMag(float64_t, bool);
float16_t f64_to_f16(float64_t);
float32_t f64_to_f32(float64_t);
#ifdef SOFTFLOAT_FAST_INT64
extFloat80_t f64_to_extF80( float64_t );
float128_t f64_to_f128( float64_t );
extFloat80_t f64_to_extF80(float64_t);
float128_t f64_to_f128(float64_t);
#endif
void f64_to_extF80M( float64_t, extFloat80_t * );
void f64_to_f128M( float64_t, float128_t * );
float64_t f64_roundToInt( float64_t, uint_fast8_t, bool );
float64_t f64_add( float64_t, float64_t );
float64_t f64_sub( 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_div( float64_t, float64_t );
float64_t f64_rem( float64_t, float64_t );
float64_t f64_sqrt( float64_t );
bool f64_eq( float64_t, float64_t );
bool f64_le( float64_t, float64_t );
bool f64_lt( float64_t, float64_t );
bool f64_eq_signaling( float64_t, float64_t );
bool f64_le_quiet( float64_t, float64_t );
bool f64_lt_quiet( float64_t, float64_t );
bool f64_isSignalingNaN( float64_t );
void f64_to_extF80M(float64_t, extFloat80_t*);
void f64_to_f128M(float64_t, float128_t*);
float64_t f64_roundToInt(float64_t, uint_fast8_t, bool);
float64_t f64_add(float64_t, float64_t);
float64_t f64_sub(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_div(float64_t, float64_t);
float64_t f64_rem(float64_t, float64_t);
float64_t f64_sqrt(float64_t);
bool f64_eq(float64_t, float64_t);
bool f64_le(float64_t, float64_t);
bool f64_lt(float64_t, float64_t);
bool f64_eq_signaling(float64_t, float64_t);
bool f64_le_quiet(float64_t, float64_t);
bool f64_lt_quiet(float64_t, float64_t);
bool f64_isSignalingNaN(float64_t);
/*----------------------------------------------------------------------------
| 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.
*----------------------------------------------------------------------------*/
#ifdef SOFTFLOAT_FAST_INT64
uint_fast32_t extF80_to_ui32( 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_fast64_t extF80_to_i64( extFloat80_t, uint_fast8_t, bool );
uint_fast32_t extF80_to_ui32_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_fast64_t extF80_to_i64_r_minMag( extFloat80_t, bool );
float16_t extF80_to_f16( extFloat80_t );
float32_t extF80_to_f32( extFloat80_t );
float64_t extF80_to_f64( extFloat80_t );
float128_t extF80_to_f128( extFloat80_t );
extFloat80_t extF80_roundToInt( extFloat80_t, uint_fast8_t, bool );
extFloat80_t extF80_add( extFloat80_t, extFloat80_t );
extFloat80_t extF80_sub( extFloat80_t, extFloat80_t );
extFloat80_t extF80_mul( extFloat80_t, extFloat80_t );
extFloat80_t extF80_div( extFloat80_t, extFloat80_t );
extFloat80_t extF80_rem( extFloat80_t, extFloat80_t );
extFloat80_t extF80_sqrt( extFloat80_t );
bool extF80_eq( extFloat80_t, extFloat80_t );
bool extF80_le( extFloat80_t, extFloat80_t );
bool extF80_lt( extFloat80_t, extFloat80_t );
bool extF80_eq_signaling( extFloat80_t, extFloat80_t );
bool extF80_le_quiet( extFloat80_t, extFloat80_t );
bool extF80_lt_quiet( extFloat80_t, extFloat80_t );
bool extF80_isSignalingNaN( extFloat80_t );
uint_fast32_t extF80_to_ui32(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_fast64_t extF80_to_i64(extFloat80_t, uint_fast8_t, bool);
uint_fast32_t extF80_to_ui32_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_fast64_t extF80_to_i64_r_minMag(extFloat80_t, bool);
float16_t extF80_to_f16(extFloat80_t);
float32_t extF80_to_f32(extFloat80_t);
float64_t extF80_to_f64(extFloat80_t);
float128_t extF80_to_f128(extFloat80_t);
extFloat80_t extF80_roundToInt(extFloat80_t, uint_fast8_t, bool);
extFloat80_t extF80_add(extFloat80_t, extFloat80_t);
extFloat80_t extF80_sub(extFloat80_t, extFloat80_t);
extFloat80_t extF80_mul(extFloat80_t, extFloat80_t);
extFloat80_t extF80_div(extFloat80_t, extFloat80_t);
extFloat80_t extF80_rem(extFloat80_t, extFloat80_t);
extFloat80_t extF80_sqrt(extFloat80_t);
bool extF80_eq(extFloat80_t, extFloat80_t);
bool extF80_le(extFloat80_t, extFloat80_t);
bool extF80_lt(extFloat80_t, extFloat80_t);
bool extF80_eq_signaling(extFloat80_t, extFloat80_t);
bool extF80_le_quiet(extFloat80_t, extFloat80_t);
bool extF80_lt_quiet(extFloat80_t, extFloat80_t);
bool extF80_isSignalingNaN(extFloat80_t);
#endif
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 );
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 );
uint_fast32_t extF80M_to_ui32_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_fast64_t extF80M_to_i64_r_minMag( const extFloat80_t *, bool );
float16_t extF80M_to_f16( const extFloat80_t * );
float32_t extF80M_to_f32( const extFloat80_t * );
float64_t extF80M_to_f64( const extFloat80_t * );
void extF80M_to_f128M( const extFloat80_t *, float128_t * );
void
extF80M_roundToInt(
const extFloat80_t *, uint_fast8_t, bool, extFloat80_t * );
void extF80M_add( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
void extF80M_sub( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
void extF80M_mul( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
void extF80M_div( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
void extF80M_rem( const extFloat80_t *, const extFloat80_t *, extFloat80_t * );
void extF80M_sqrt( const extFloat80_t *, extFloat80_t * );
bool extF80M_eq( const extFloat80_t *, const extFloat80_t * );
bool extF80M_le( const extFloat80_t *, const extFloat80_t * );
bool extF80M_lt( const extFloat80_t *, const extFloat80_t * );
bool extF80M_eq_signaling( const extFloat80_t *, const extFloat80_t * );
bool extF80M_le_quiet( const extFloat80_t *, const extFloat80_t * );
bool extF80M_lt_quiet( const extFloat80_t *, const extFloat80_t * );
bool extF80M_isSignalingNaN( const extFloat80_t * );
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);
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);
uint_fast32_t extF80M_to_ui32_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_fast64_t extF80M_to_i64_r_minMag(const extFloat80_t*, bool);
float16_t extF80M_to_f16(const extFloat80_t*);
float32_t extF80M_to_f32(const extFloat80_t*);
float64_t extF80M_to_f64(const extFloat80_t*);
void extF80M_to_f128M(const extFloat80_t*, float128_t*);
void extF80M_roundToInt(const extFloat80_t*, uint_fast8_t, bool, extFloat80_t*);
void extF80M_add(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_sub(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_mul(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_div(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_rem(const extFloat80_t*, const extFloat80_t*, extFloat80_t*);
void extF80M_sqrt(const extFloat80_t*, extFloat80_t*);
bool extF80M_eq(const extFloat80_t*, const extFloat80_t*);
bool extF80M_le(const extFloat80_t*, const extFloat80_t*);
bool extF80M_lt(const extFloat80_t*, const extFloat80_t*);
bool extF80M_eq_signaling(const extFloat80_t*, const extFloat80_t*);
bool extF80M_le_quiet(const extFloat80_t*, 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.
*----------------------------------------------------------------------------*/
#ifdef SOFTFLOAT_FAST_INT64
uint_fast32_t f128_to_ui32( 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_fast64_t f128_to_i64( float128_t, uint_fast8_t, bool );
uint_fast32_t f128_to_ui32_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_fast64_t f128_to_i64_r_minMag( float128_t, bool );
float16_t f128_to_f16( float128_t );
float32_t f128_to_f32( float128_t );
float64_t f128_to_f64( float128_t );
extFloat80_t f128_to_extF80( float128_t );
float128_t f128_roundToInt( float128_t, uint_fast8_t, bool );
float128_t f128_add( float128_t, float128_t );
float128_t f128_sub( 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_div( float128_t, float128_t );
float128_t f128_rem( float128_t, float128_t );
float128_t f128_sqrt( float128_t );
bool f128_eq( float128_t, float128_t );
bool f128_le( float128_t, float128_t );
bool f128_lt( float128_t, float128_t );
bool f128_eq_signaling( float128_t, float128_t );
bool f128_le_quiet( float128_t, float128_t );
bool f128_lt_quiet( float128_t, float128_t );
bool f128_isSignalingNaN( float128_t );
uint_fast32_t f128_to_ui32(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_fast64_t f128_to_i64(float128_t, uint_fast8_t, bool);
uint_fast32_t f128_to_ui32_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_fast64_t f128_to_i64_r_minMag(float128_t, bool);
float16_t f128_to_f16(float128_t);
float32_t f128_to_f32(float128_t);
float64_t f128_to_f64(float128_t);
extFloat80_t f128_to_extF80(float128_t);
float128_t f128_roundToInt(float128_t, uint_fast8_t, bool);
float128_t f128_add(float128_t, float128_t);
float128_t f128_sub(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_div(float128_t, float128_t);
float128_t f128_rem(float128_t, float128_t);
float128_t f128_sqrt(float128_t);
bool f128_eq(float128_t, float128_t);
bool f128_le(float128_t, float128_t);
bool f128_lt(float128_t, float128_t);
bool f128_eq_signaling(float128_t, float128_t);
bool f128_le_quiet(float128_t, float128_t);
bool f128_lt_quiet(float128_t, float128_t);
bool f128_isSignalingNaN(float128_t);
#endif
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 );
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 );
uint_fast32_t f128M_to_ui32_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_fast64_t f128M_to_i64_r_minMag( const float128_t *, bool );
float16_t f128M_to_f16( const float128_t * );
float32_t f128M_to_f32( const float128_t * );
float64_t f128M_to_f64( const float128_t * );
void f128M_to_extF80M( const float128_t *, extFloat80_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_sub( const float128_t *, const float128_t *, float128_t * );
void f128M_mul( const float128_t *, const float128_t *, float128_t * );
void
f128M_mulAdd(
const float128_t *, const float128_t *, const float128_t *, float128_t *
);
void f128M_div( 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 * );
bool f128M_eq( const float128_t *, const float128_t * );
bool f128M_le( const float128_t *, const float128_t * );
bool f128M_lt( const float128_t *, const float128_t * );
bool f128M_eq_signaling( const float128_t *, 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 * );
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);
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);
uint_fast32_t f128M_to_ui32_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_fast64_t f128M_to_i64_r_minMag(const float128_t*, bool);
float16_t f128M_to_f16(const float128_t*);
float32_t f128M_to_f32(const float128_t*);
float64_t f128M_to_f64(const float128_t*);
void f128M_to_extF80M(const float128_t*, extFloat80_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_sub(const float128_t*, const float128_t*, float128_t*);
void f128M_mul(const float128_t*, const float128_t*, float128_t*);
void f128M_mulAdd(const float128_t*, const float128_t*, const float128_t*, float128_t*);
void f128M_div(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*);
bool f128M_eq(const float128_t*, const float128_t*);
bool f128M_le(const float128_t*, const float128_t*);
bool f128M_lt(const float128_t*, const float128_t*);
bool f128M_eq_signaling(const float128_t*, 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

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
| (typically 'float' and 'double', and possibly 'long double').
*----------------------------------------------------------------------------*/
typedef struct { uint16_t v; } float16_t;
typedef struct { uint32_t v; } float32_t;
typedef struct { uint64_t v; } float64_t;
typedef struct { uint64_t v[2]; } float128_t;
typedef struct {
uint16_t v;
} float16_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
@ -58,9 +66,15 @@ typedef struct { uint64_t v[2]; } float128_t;
| named 'signif'.
*----------------------------------------------------------------------------*/
#ifdef LITTLEENDIAN
struct extFloat80M { uint64_t signif; uint16_t signExp; };
struct extFloat80M {
uint64_t signif;
uint16_t signExp;
};
#else
struct extFloat80M { uint16_t signExp; uint64_t signif; };
struct extFloat80M {
uint16_t signExp;
uint64_t signif;
};
#endif
/*----------------------------------------------------------------------------
@ -78,4 +92,3 @@ struct extFloat80M { uint16_t signExp; uint64_t signif; };
typedef struct extFloat80M extFloat80_t;
#endif

View File

@ -50,45 +50,67 @@ public:
virtual ~hwl() = default;
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;
};
template<typename BASE>
inline hwl<BASE>::hwl(feature_config cfg): BASE(cfg) {
for (unsigned addr = 0x800; addr < 0x803; ++addr){
template <typename BASE>
inline hwl<BASE>::hwl(feature_config cfg)
: BASE(cfg) {
for(unsigned addr = 0x800; addr < 0x803; ++addr) {
this->register_custom_csr_rd(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_wr(addr);
}
}
template<typename BASE>
inline iss::status iss::arch::hwl<BASE>::read_custom_csr_reg(unsigned addr, reg_t &val) {
switch(addr){
case 0x800: val = this->reg.lpstart0; break;
case 0x801: val = this->reg.lpend0; 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;
template <typename BASE> inline iss::status iss::arch::hwl<BASE>::read_custom_csr_reg(unsigned addr, reg_t& val) {
switch(addr) {
case 0x800:
val = this->reg.lpstart0;
break;
case 0x801:
val = this->reg.lpend0;
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;
}
template<typename BASE>
inline iss::status iss::arch::hwl<BASE>::write_custom_csr_reg(unsigned addr, reg_t val) {
switch(addr){
case 0x800: this->reg.lpstart0 = val; break;
case 0x801: this->reg.lpend0 = 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;
template <typename BASE> inline iss::status iss::arch::hwl<BASE>::write_custom_csr_reg(unsigned addr, reg_t val) {
switch(addr) {
case 0x800:
this->reg.lpstart0 = val;
break;
case 0x801:
this->reg.lpend0 = 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;
}
@ -96,5 +118,4 @@ inline iss::status iss::arch::hwl<BASE>::write_custom_csr_reg(unsigned addr, reg
} // namespace arch
} // namespace iss
#endif /* _RISCV_HART_M_P_H */

View File

@ -43,7 +43,7 @@ namespace arch {
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 {
/* user-level CSR */
@ -51,17 +51,17 @@ enum riscv_csr {
ustatus = 0x000,
uie = 0x004,
utvec = 0x005,
utvt = 0x007, //CLIC
utvt = 0x007, // CLIC
// User Trap Handling
uscratch = 0x040,
uepc = 0x041,
ucause = 0x042,
utval = 0x043,
uip = 0x044,
uxnti = 0x045, //CLIC
uintstatus = 0xCB1, // MRW Current interrupt levels (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)
uxnti = 0x045, // CLIC
uintstatus = 0xCB1, // MRW Current interrupt levels (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)
uscratchcswl = 0x049, // MRW Conditional scratch swap on level change (CLIC)
// User Floating-Point CSRs
fflags = 0x001,
@ -112,17 +112,17 @@ enum riscv_csr {
mie = 0x304,
mtvec = 0x305,
mcounteren = 0x306,
mtvt = 0x307, //CLIC
mtvt = 0x307, // CLIC
// Machine Trap Handling
mscratch = 0x340,
mepc = 0x341,
mcause = 0x342,
mtval = 0x343,
mip = 0x344,
mxnti = 0x345, //CLIC
mintstatus = 0xFB1, // MRW Current interrupt levels (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)
mxnti = 0x345, // CLIC
mintstatus = 0xFB1, // MRW Current interrupt levels (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)
mscratchcswl = 0x349, // MRW Conditional scratch swap on level change (CLIC)
// Physical Memory Protection
pmpcfg0 = 0x3A0,
@ -175,7 +175,6 @@ enum riscv_csr {
dscratch1 = 0x7B3
};
enum {
PGSHIFT = 12,
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); }
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 {
ISA_A = 1,
@ -256,49 +255,49 @@ public:
: 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);
switch (offs & 0x3) {
switch(offs & 0x3) {
case 0:
for (auto i = 0U; i < length; ++i)
for(auto i = 0U; i < length; ++i)
*(data + i) = *(reg_ptr + i);
break;
break;
case 1:
for (auto i = 0U; i < length; ++i)
for(auto i = 0U; i < length; ++i)
*(data + i) = *(reg_ptr + 1 + i);
break;
break;
case 2:
for (auto i = 0U; i < length; ++i)
for(auto i = 0U; i < length; ++i)
*(data + i) = *(reg_ptr + 2 + i);
break;
break;
case 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);
switch (offs & 0x3) {
switch(offs & 0x3) {
case 0:
for (auto i = 0U; i < length; ++i)
for(auto i = 0U; i < length; ++i)
*(reg_ptr + i) = *(data + i);
break;
break;
case 1:
for (auto i = 0U; i < length; ++i)
for(auto i = 0U; i < length; ++i)
*(reg_ptr + 1 + i) = *(data + i);
break;
break;
case 2:
for (auto i = 0U; i < length; ++i)
for(auto i = 0U; i < length; ++i)
*(reg_ptr + 2 + i) = *(data + i);
break;
break;
case 3:
*(reg_ptr + 3) = *data ;
break;
*(reg_ptr + 3) = *data;
break;
}
}
}
}
} // namespace arch
} // namespace iss
#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 "util/ities.h"
#include <util/logging.h>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <util/logging.h>
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_aliases;
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 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;
tgc5c::tgc5c() = default;
tgc5c::tgc5c() = default;
tgc5c::~tgc5c() = default;
void tgc5c::reset(uint64_t address) {
auto base_ptr = reinterpret_cast<traits<tgc5c>::reg_t*>(get_regs_base_ptr());
for(size_t i=0; i<traits<tgc5c>::NUM_REGS; ++i)
*(base_ptr+i)=0;
reg.PC=address;
reg.NEXT_PC=reg.PC;
reg.PRIV=0x3;
reg.trap_state=0;
reg.icount=0;
for(size_t i = 0; i < traits<tgc5c>::NUM_REGS; ++i)
*(base_ptr + i) = 0;
reg.PC = address;
reg.NEXT_PC = reg.PC;
reg.PRIV = 0x3;
reg.trap_state = 0;
reg.icount = 0;
}
uint8_t *tgc5c::get_regs_base_ptr() {
return reinterpret_cast<uint8_t*>(&reg);
}
uint8_t* tgc5c::get_regs_base_ptr() { return reinterpret_cast<uint8_t*>(&reg); }
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);
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);
}

View File

@ -46,43 +46,103 @@ struct tgc5c;
template <> struct traits<tgc5c> {
constexpr static char const* const core_type = "TGC5C";
static constexpr std::array<const char*, 36> reg_names{
{"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"}};
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"}};
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};
static constexpr std::array<const char*, 36> reg_names{{"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"}};
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"}};
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;
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 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 phys_addr_t = iss::typed_addr_t<iss::address_type::PHYSICAL>;
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,8,32,32,32,64,64,64,32,32}};
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, 8, 32, 32, 32, 64, 64, 64, 32, 32}};
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);
enum sreg_flag_e { FLAGS };
enum mem_type_e { MEM, FENCE, RES, CSR };
enum class opcode_e {
LUI = 0,
AUIPC = 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 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;
tgc5c();
~tgc5c();
void reset(uint64_t address=0) override;
void reset(uint64_t address = 0) override;
uint8_t* get_regs_base_ptr() override;
@ -201,44 +261,43 @@ struct tgc5c: public arch_if {
inline uint32_t get_last_branch() { return reg.last_branch; }
#pragma pack(push, 1)
struct TGC5C_regs {
uint32_t X0 = 0;
uint32_t X1 = 0;
uint32_t X2 = 0;
uint32_t X3 = 0;
uint32_t X4 = 0;
uint32_t X5 = 0;
uint32_t X6 = 0;
uint32_t X7 = 0;
uint32_t X8 = 0;
uint32_t X9 = 0;
uint32_t X10 = 0;
uint32_t X11 = 0;
uint32_t X12 = 0;
uint32_t X13 = 0;
uint32_t X14 = 0;
uint32_t X15 = 0;
uint32_t X16 = 0;
uint32_t X17 = 0;
uint32_t X18 = 0;
uint32_t X19 = 0;
uint32_t X20 = 0;
uint32_t X21 = 0;
uint32_t X22 = 0;
uint32_t X23 = 0;
uint32_t X24 = 0;
uint32_t X25 = 0;
uint32_t X26 = 0;
uint32_t X27 = 0;
uint32_t X28 = 0;
uint32_t X29 = 0;
uint32_t X30 = 0;
uint32_t X31 = 0;
uint32_t PC = 0;
uint32_t NEXT_PC = 0;
uint8_t PRIV = 0;
struct TGC5C_regs {
uint32_t X0 = 0;
uint32_t X1 = 0;
uint32_t X2 = 0;
uint32_t X3 = 0;
uint32_t X4 = 0;
uint32_t X5 = 0;
uint32_t X6 = 0;
uint32_t X7 = 0;
uint32_t X8 = 0;
uint32_t X9 = 0;
uint32_t X10 = 0;
uint32_t X11 = 0;
uint32_t X12 = 0;
uint32_t X13 = 0;
uint32_t X14 = 0;
uint32_t X15 = 0;
uint32_t X16 = 0;
uint32_t X17 = 0;
uint32_t X18 = 0;
uint32_t X19 = 0;
uint32_t X20 = 0;
uint32_t X21 = 0;
uint32_t X22 = 0;
uint32_t X23 = 0;
uint32_t X24 = 0;
uint32_t X25 = 0;
uint32_t X26 = 0;
uint32_t X27 = 0;
uint32_t X28 = 0;
uint32_t X29 = 0;
uint32_t X30 = 0;
uint32_t X31 = 0;
uint32_t PC = 0;
uint32_t NEXT_PC = 0;
uint8_t PRIV = 0;
uint32_t DPC = 0;
uint32_t trap_state = 0, pending_trap = 0;
uint64_t icount = 0;
@ -249,14 +308,13 @@ struct tgc5c: public arch_if {
} reg;
#pragma pack(pop)
std::array<address_type, 4> addr_mode;
uint64_t interrupt_sim=0;
uint32_t get_fcsr(){return 0;}
void set_fcsr(uint32_t val){}
uint64_t interrupt_sim = 0;
uint32_t get_fcsr() { return 0; }
void set_fcsr(uint32_t val) {}
};
}
}
} // namespace arch
} // namespace iss
#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>;
#endif
#ifdef CORE_TGC5C_XRB_NN
#include "riscv_hart_m_p.h"
#include "hwl.h"
#include "riscv_hart_m_p.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>>;
#endif
#ifdef CORE_TGC5D
#include "riscv_hart_mu_p.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
#ifdef CORE_TGC5D_XRB_MAC
#include "riscv_hart_mu_p.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
#ifdef CORE_TGC5D_XRB_NN
#include "riscv_hart_mu_p.h"
#include "hwl.h"
#include "riscv_hart_mu_p.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
#ifdef CORE_TGC5E
#include "riscv_hart_mu_p.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
#ifdef CORE_TGC5X
#include "riscv_hart_mu_p.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

View File

@ -36,25 +36,27 @@
#define _RISCV_HART_M_P_WT_CACHE_H
#include <iss/vm_types.h>
#include <util/ities.h>
#include <vector>
#include <map>
#include <memory>
#include <util/ities.h>
#include <vector>
namespace iss {
namespace arch {
namespace cache {
enum class state { INVALID, VALID};
enum class state { INVALID, VALID };
struct line {
uint64_t tag_addr{0};
state st{state::INVALID};
std::vector<uint8_t> data;
line(unsigned line_sz): data(line_sz) {}
line(unsigned line_sz)
: data(line_sz) {}
};
struct set {
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 {
std::vector<set> sets;
@ -62,14 +64,14 @@ struct cache {
cache(unsigned size, unsigned line_sz, unsigned ways) {
line const ref_line{line_sz};
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 {
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
template <typename BASE> class wt_cache : public BASE {
@ -89,78 +91,73 @@ public:
unsigned ways{1};
uint64_t io_address{0xf0000000};
uint64_t io_addr_mask{0xf0000000};
protected:
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 read_cache(phys_addr_t addr, unsigned, uint8_t* 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_write_f> cache_mem_wr_delegate;
std::unique_ptr<cache::cache> dcache_ptr;
std::unique_ptr<cache::cache> icache_ptr;
size_t get_way_select() {
return 0;
}
size_t get_way_select() { return 0; }
};
template<typename BASE>
template <typename BASE>
inline wt_cache<BASE>::wt_cache(feature_config cfg)
:BASE(cfg)
: BASE(cfg)
, 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(
[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 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); });
cache_mem_rd_delegate = cb.first;
cache_mem_wr_delegate = cb.second;
}
template<typename BASE>
iss::status iss::arch::wt_cache<BASE>::read_cache(phys_addr_t a, unsigned l, uint8_t* const d) {
template <typename BASE> iss::status iss::arch::wt_cache<BASE>::read_cache(phys_addr_t a, unsigned l, uint8_t* const d) {
if(!icache_ptr) {
icache_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) {
auto set_addr=(a.val&(size-1))>>util::ilog2(line_sz*ways);
auto tag_addr=a.val>>util::ilog2(line_sz);
auto& set = (is_fetch(a.access)?icache_ptr:dcache_ptr)->sets[set_addr];
for(auto& cl: set.ways) {
if(cl.st==cache::state::VALID && cl.tag_addr==tag_addr) {
auto start_addr = a.val&(line_sz-1);
for(auto i = 0U; i<l; ++i)
d[i] = cl.data[start_addr+i];
if((a.val & io_addr_mask) != io_address) {
auto set_addr = (a.val & (size - 1)) >> util::ilog2(line_sz * ways);
auto tag_addr = a.val >> util::ilog2(line_sz);
auto& set = (is_fetch(a.access) ? icache_ptr : dcache_ptr)->sets[set_addr];
for(auto& cl : set.ways) {
if(cl.st == cache::state::VALID && cl.tag_addr == tag_addr) {
auto start_addr = a.val & (line_sz - 1);
for(auto i = 0U; i < l; ++i)
d[i] = cl.data[start_addr + i];
return iss::Ok;
}
}
auto& cl = set.ways[get_way_select()];
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());
cl.tag_addr=tag_addr;
cl.st=cache::state::VALID;
auto start_addr = a.val&(line_sz-1);
for(auto i = 0U; i<l; ++i)
d[i] = cl.data[start_addr+i];
cl.tag_addr = tag_addr;
cl.st = cache::state::VALID;
auto start_addr = a.val & (line_sz - 1);
for(auto i = 0U; i < l; ++i)
d[i] = cl.data[start_addr + i];
return iss::Ok;
} else
return cache_mem_rd_delegate(a, l, d);
}
template<typename BASE>
iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, const uint8_t* const d) {
template <typename BASE> iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, const uint8_t* const d) {
if(!dcache_ptr)
dcache_ptr.reset(new cache::cache(size, line_sz, ways));
auto res = cache_mem_wr_delegate(a, l, d);
if(res == iss::Ok && ((a.val&io_addr_mask) != io_address)) {
auto set_addr=(a.val&(size-1))>>util::ilog2(line_sz*ways);
auto tag_addr=a.val>>util::ilog2(line_sz);
if(res == iss::Ok && ((a.val & io_addr_mask) != io_address)) {
auto set_addr = (a.val & (size - 1)) >> util::ilog2(line_sz * ways);
auto tag_addr = a.val >> util::ilog2(line_sz);
auto& set = dcache_ptr->sets[set_addr];
for(auto& cl: set.ways) {
if(cl.st==cache::state::VALID && cl.tag_addr==tag_addr) {
auto start_addr = a.val&(line_sz-1);
for(auto i = 0U; i<l; ++i)
cl.data[start_addr+i] = d[i];
for(auto& cl : set.ways) {
if(cl.st == cache::state::VALID && cl.tag_addr == tag_addr) {
auto start_addr = a.val & (line_sz - 1);
for(auto i = 0U; i < l; ++i)
cl.data[start_addr + i] = d[i];
break;
}
}
@ -168,8 +165,6 @@ iss::status iss::arch::wt_cache<BASE>::write_cache(phys_addr_t a, unsigned l, co
return res;
}
} // namespace arch
} // namespace iss

View File

@ -53,20 +53,20 @@ using namespace iss::debugger;
template <typename ARCH> class riscv_target_adapter : public target_adapter_base {
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)
, core(core) {}
/*============== Thread Control ===============================*/
/* Set generic thread */
status set_gen_thread(rp_thread_ref &thread) override;
status set_gen_thread(rp_thread_ref& thread) override;
/* Set control thread */
status set_ctrl_thread(rp_thread_ref &thread) override;
status set_ctrl_thread(rp_thread_ref& thread) override;
/* 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 ================================*/
@ -74,79 +74,77 @@ public:
target byte order. If register is not available
corresponding bytes in avail_buf are 0, otherwise
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
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
target byte order. If register is not available
corresponding bytes in avail_buf are 0, otherwise
avail buf is 1 */
status read_single_register(unsigned int reg_no, std::vector<uint8_t> &buf,
std::vector<uint8_t> &avail_buf) override;
status read_single_register(unsigned int reg_no, std::vector<uint8_t>& buf, std::vector<uint8_t>& avail_buf) override;
/* Write one register. buf is 4-byte aligned and it is in target byte
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 =====================*/
/* Read memory, buf is 4-bytes aligned and it is in target
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
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,
size_t &num, bool &done) override;
status thread_list_query(int first, const rp_thread_ref& arg, std::vector<rp_thread_ref>& result, size_t max_num, size_t& num,
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 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,
std::function<void(unsigned)> stop_callback) override;
status resume_from_addr(bool step, int sig, uint64_t addr, rp_thread_ref thread, 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:
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;
};
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;
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;
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;
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.
*/
template <typename ARCH>
status riscv_target_adapter<ARCH>::thread_list_query(int first, const rp_thread_ref &arg,
std::vector<rp_thread_ref> &result, size_t max_num, size_t &num,
bool &done) {
if (first == 0) {
status riscv_target_adapter<ARCH>::thread_list_query(int first, const rp_thread_ref& arg, std::vector<rp_thread_ref>& result,
size_t max_num, size_t& num, bool& done) {
if(first == 0) {
result.clear();
result.push_back(thread_idx);
num = 1;
@ -171,23 +168,22 @@ status riscv_target_adapter<ARCH>::thread_list_query(int first, const rp_thread_
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;
return Ok;
}
template <typename ARCH>
status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, std::vector<uint8_t> &avail) {
template <typename ARCH> status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
LOG(TRACE) << "reading target registers";
// return idx<0?:;
data.clear();
avail.clear();
const uint8_t *reg_base = core->get_regs_base_ptr();
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) {
const uint8_t* reg_base = core->get_regs_base_ptr();
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) {
auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8;
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));
avail.push_back(0xff);
}
@ -210,19 +206,19 @@ status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t> &data, st
return Ok;
}
template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(const std::vector<uint8_t> &data) {
auto start_reg=arch::traits<ARCH>::X0;
auto *reg_base = core->get_regs_base_ptr();
template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(const std::vector<uint8_t>& data) {
auto start_reg = arch::traits<ARCH>::X0;
auto* reg_base = core->get_regs_base_ptr();
auto iter = data.data();
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) {
if(e_ext && reg_no>15){
if(reg_no==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) {
if(e_ext && reg_no > 15) {
if(reg_no == 32) {
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];
std::copy(iter, iter + reg_width, reg_base);
} 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 iter = (uint8_t*)&zero_val;
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>
status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t> &data,
std::vector<uint8_t> &avail) {
if (reg_no < 65) {
status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
if(reg_no < 65) {
// auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename
// 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;
data.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;
}
template <typename ARCH>
status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t> &data) {
if (reg_no < 65) {
auto *reg_base = core->get_regs_base_ptr();
template <typename ARCH> status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t>& data) {
if(reg_no < 65) {
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 offset = traits<ARCH>::reg_byte_offsets[reg_no];
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;
}
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 f = [&]() -> status { return core->read(a, data.size(), data.data()); };
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 f = [&]() -> status { return core->write(a, data.size(), data.data()); };
return srv->execute_syncronized(f);
}
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;
}
template <typename ARCH>
status riscv_target_adapter<ARCH>::offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) {
template <typename ARCH> status riscv_target_adapter<ARCH>::offsets_query(uint64_t& text, uint64_t& data, uint64_t& bss) {
text = 0;
data = 0;
bss = 0;
return Ok;
}
template <typename ARCH> status riscv_target_adapter<ARCH>::crc_query(uint64_t addr, size_t len, uint32_t &val) {
return NotSupported;
}
template <typename ARCH> status riscv_target_adapter<ARCH>::crc_query(uint64_t addr, size_t len, uint32_t& val) { return NotSupported; }
template <typename ARCH> status riscv_target_adapter<ARCH>::raw_query(std::string in_buf, std::string &out_buf) {
return NotSupported;
}
template <typename ARCH> status riscv_target_adapter<ARCH>::raw_query(std::string in_buf, std::string& out_buf) { return NotSupported; }
template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int first, std::string &out_buf) {
if (first) {
template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int first, std::string& out_buf) {
if(first) {
out_buf = fmt::format("m{:x}", thread_idx.val);
} else {
out_buf = "l";
@ -317,8 +306,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int
return Ok;
}
template <typename ARCH>
status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) {
template <typename ARCH> status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref& thread, std::string& out_buf) {
std::array<char, 20> buf;
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);
@ -326,7 +314,7 @@ status riscv_target_adapter<ARCH>::threadextrainfo_query(const rp_thread_ref &th
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";
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 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);
LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex
<< saddr.val << std::dec;
LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex << saddr.val
<< std::dec;
LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints";
return Ok;
}
@ -356,9 +344,8 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::remove_break(break_t
case HW_EXEC: {
auto saddr = map_addr({iss::access_type::FETCH, iss::address_type::PHYSICAL, 0, addr});
unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val);
if (handle) {
LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val
<< std::dec;
if(handle) {
LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val << std::dec;
// TODO: check length of addr range
target_adapter_base::bp_lut.removeEntry(handle);
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>
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) {
auto *reg_base = core->get_regs_base_ptr();
std::function<void(unsigned)> stop_callback) {
auto* reg_base = core->get_regs_base_ptr();
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];
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);
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\">"
"<target><architecture>riscv:rv32</architecture>"
//" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n"
//" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n"
//" </feature>\n"
"</target>"};
"<target><architecture>riscv:rv32</architecture>"
//" <feature name=\"org.gnu.gdb.riscv.rv32i\">\n"
//" <reg name=\"x0\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x1\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x2\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x3\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x4\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x5\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x6\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x7\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x8\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x9\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x10\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x11\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x12\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x13\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x14\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x15\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x16\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x17\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x18\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x19\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x20\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x21\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x22\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x23\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x24\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x25\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x26\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x27\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x28\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x29\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x30\" bitsize=\"32\" group=\"general\"/>\n"
//" <reg name=\"x31\" bitsize=\"32\" group=\"general\"/>\n"
//" </feature>\n"
"</target>"};
out_buf = res;
return Ok;
}
@ -468,7 +455,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std
</target>
*/
}
}
} // namespace debugger
} // namespace iss
#endif /* _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ */

View File

@ -33,21 +33,20 @@
#ifndef _ISS_FACTORY_H_
#define _ISS_FACTORY_H_
#include <algorithm>
#include <functional>
#include <iss/iss.h>
#include <memory>
#include <unordered_map>
#include <functional>
#include <string>
#include <algorithm>
#include <unordered_map>
#include <vector>
namespace iss {
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>
std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_port){
template <typename PLAT> std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_port) {
using core_type = typename PLAT::core;
core_type* lcpu = new PLAT();
if(backend == "interp")
@ -63,44 +62,45 @@ std::tuple<cpu_ptr, vm_ptr> create_cpu(std::string const& backend, unsigned gdb_
return {nullptr, nullptr};
}
class core_factory {
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 create_fn = std::function<base_t(unsigned, void*) >;
using registry_t = std::unordered_map<std::string, create_fn> ;
using create_fn = std::function<base_t(unsigned, void*)>;
using registry_t = std::unordered_map<std::string, create_fn>;
registry_t registry;
core_factory() = default;
core_factory(const core_factory &) = delete;
core_factory & operator=(const core_factory &) = delete;
core_factory(const core_factory&) = delete;
core_factory& operator=(const core_factory&) = delete;
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;
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);
if (regEntry != registry.end())
if(regEntry != registry.end())
return regEntry->second(gdb_port, init_data);
return {nullptr, nullptr};
}
std::vector<std::string> get_names() {
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){
return p.first;
});
std::transform(std::begin(registry), std::end(registry), std::begin(keys),
[](std::pair<std::string, create_fn> const& p) { return p.first; });
return keys;
}
};
}
} // namespace iss
#endif /* _ISS_FACTORY_H_ */

View File

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

View File

@ -37,16 +37,16 @@
#include "iss/instrumentation_if.h"
#include "iss/vm_plugin.h"
#include <functional>
#include <string>
#include <unordered_map>
#include <vector>
#include <functional>
namespace iss {
namespace plugin {
class cycle_estimate: public vm_plugin {
class cycle_estimate : public vm_plugin {
struct instr_desc {
size_t size{0};
bool is_branch{false};
@ -58,32 +58,32 @@ class cycle_estimate: public vm_plugin {
public:
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);
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; };
void callback(instr_info_t instr_info) override;
private:
iss::instrumentation_if *instr_if{nullptr};
uint32_t* reg_base_ptr {nullptr};
iss::instrumentation_if* instr_if{nullptr};
uint32_t* reg_base_ptr{nullptr};
instr_desc illegal_desc{};
std::vector<instr_desc> delays;
unsigned current_delay{0};
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;
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::string config_file_name;
};
}
}
} // namespace plugin
} // namespace iss
#endif /* _ISS_PLUGIN_CYCLE_ESTIMATE_H_ */

View File

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

View File

@ -53,19 +53,19 @@ class instruction_count : public iss::vm_plugin {
public:
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);
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; };
@ -75,7 +75,7 @@ private:
std::vector<instr_delay> delays;
std::vector<uint64_t> rep_counts;
};
}
}
} // namespace plugin
} // namespace iss
#endif /* _ISS_PLUGIN_INSTRUCTION_COUNTER_H_ */

View File

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

View File

@ -55,8 +55,10 @@
// clang-format on
#define STR(X) #X
#define CREATE_CORE(CN) \
if (type == STR(CN)) { std::tie(cpu, vm) = create_core<CN ## _plat_type>(backend, gdb_port, hart_id); } else
#define CREATE_CORE(CN) \
if(type == STR(CN)) { \
std::tie(cpu, vm) = create_core<CN##_plat_type>(backend, gdb_port, hart_id); \
} else
#ifdef HAS_SCV
#include <scv.h>
@ -87,23 +89,22 @@ using namespace sc_core;
namespace {
iss::debugger::encoder_decoder encdec;
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,
debugger::target_adapter_if *tgt_adapter) {
if (argc > 1) {
if (strcasecmp(argv[1], "print_time") == 0) {
int cmd_sysc(int argc, char* argv[], debugger::out_func of, debugger::data_func df, debugger::target_adapter_if* tgt_adapter) {
if(argc > 1) {
if(strcasecmp(argv[1], "print_time") == 0) {
std::string t = sc_time_stamp().to_string();
of(t.c_str());
std::array<char, 64> buf;
encdec.enc_string(t.c_str(), buf.data(), 63);
df(buf.data());
return Ok;
} else if (strcasecmp(argv[1], "break") == 0) {
} else if(strcasecmp(argv[1], "break") == 0) {
sc_time t;
if (argc == 4) {
if(argc == 4) {
t = scc::parse_from_string(argv[2], argv[3]);
} else if (argc == 3) {
} else if(argc == 3) {
t = scc::parse_from_string(argv[2]);
} else
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 vm_ptr= std::unique_ptr<iss::vm_if>;
using vm_ptr = std::unique_ptr<iss::vm_if>;
class core_wrapper {
public:
core_wrapper(core_complex *owner) : owner(owner) { }
core_wrapper(core_complex* owner)
: owner(owner) {}
void reset(uint64_t addr){vm->reset(addr);}
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){
void reset(uint64_t addr) { vm->reset(addr); }
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) {
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<uint64_t(void)> get_state;
@ -138,26 +141,26 @@ public:
std::function<void(bool)> set_interrupt_execution;
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){
auto & f = sysc::iss_factory::instance();
if(type.size()==0 || type == "?") {
std::cout<<"Available cores: "<<util::join(f.get_names(), ", ")<<std::endl;
void create_cpu(std::string const& type, std::string const& backend, unsigned gdb_port, uint32_t hart_id) {
auto& f = sysc::iss_factory::instance();
if(type.size() == 0 || type == "?") {
std::cout << "Available cores: " << util::join(f.get_names(), ", ") << std::endl;
sc_core::sc_stop();
} else if (type.find('|') != std::string::npos) {
std::tie(cpu, vm) = f.create(type+"|"+backend);
} else if(type.find('|') != std::string::npos) {
std::tie(cpu, vm) = f.create(type + "|" + backend);
} else {
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);
} else {
std::tie(cpu, vm) = f.create(type + "|m_p|" + backend, gdb_port, owner);
}
}
}
if(!cpu ){
SCCFATAL() << "Could not create cpu for isa " << type << " and backend " <<backend;
if(!cpu) {
SCCFATAL() << "Could not create cpu for isa " << type << " and backend " << backend;
}
if(!vm ){
SCCFATAL() << "Could not create vm for isa " << type << " and backend " <<backend;
if(!vm) {
SCCFATAL() << "Could not create vm for isa " << type << " and backend " << backend;
}
auto* sc_cpu_if = reinterpret_cast<sc_core_adapter_if*>(cpu.get());
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); };
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();
if (srv) tgt_adapter = srv->get_target();
if (tgt_adapter)
tgt_adapter->add_custom_command(
{"sysc", [this](int argc, char *argv[], debugger::out_func of,
debugger::data_func df) -> int { return cmd_sysc(argc, argv, of, df, tgt_adapter); },
"SystemC sub-commands: break <time>, print_time"});
auto* srv = debugger::server<debugger::gdb_session>::get();
if(srv)
tgt_adapter = srv->get_target();
if(tgt_adapter)
tgt_adapter->add_custom_command({"sysc",
[this](int argc, char* argv[], debugger::out_func of, debugger::data_func df) -> int {
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};
sc_cpu_ptr cpu{nullptr};
iss::debugger::target_adapter_if *tgt_adapter{nullptr};
iss::debugger::target_adapter_if* tgt_adapter{nullptr};
};
struct core_trace {
//! transaction recording database
scv_tr_db *m_db{nullptr};
scv_tr_db* m_db{nullptr};
//! blocking transaction recording stream handle
scv_tr_stream *stream_handle{nullptr};
scv_tr_stream* stream_handle{nullptr};
//! 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;
};
SC_HAS_PROCESS(core_complex);// NOLINT
SC_HAS_PROCESS(core_complex); // NOLINT
#ifndef CWR_SYSTEMC
core_complex::core_complex(sc_module_name const& name)
: sc_module(name)
, fetch_lut(tlm_dmi_ext())
, read_lut(tlm_dmi_ext())
, write_lut(tlm_dmi_ext())
{
init();
, write_lut(tlm_dmi_ext()) {
init();
}
#endif
void core_complex::init(){
trc=new core_trace();
void core_complex::init() {
trc = new core_trace();
ibus.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void {
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);
}
});
dbus.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void {
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);
}
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);
}
});
@ -234,53 +237,53 @@ void core_complex::init(){
SC_METHOD(ext_irq_cb);
sensitive << ext_irq_i;
SC_METHOD(local_irq_cb);
for(auto pin:local_irq_i)
for(auto pin : local_irq_i)
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
sensitive<<clk_i;
sensitive << clk_i;
#else
sensitive<<curr_clk;
t2t.reset(new scc::tick2time{"t2t"});
t2t->clk_i(clk_i);
t2t->clk_o(curr_clk);
sensitive << curr_clk;
t2t.reset(new scc::tick2time{"t2t"});
t2t->clk_i(clk_i);
t2t->clk_o(curr_clk);
#endif
}
core_complex::~core_complex(){
core_complex::~core_complex() {
delete cpu;
delete trc;
for (auto *p : plugin_list)
for(auto* p : plugin_list)
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() {
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 = 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));
sc_assert(cpu->vm!=nullptr);
sc_assert(cpu->vm != 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), ';');
for (std::string const& opt_val : p) {
std::string plugin_name=opt_val;
for(std::string const& opt_val : p) {
std::string plugin_name = opt_val;
std::string filename{"cycles.txt"};
std::size_t found = opt_val.find('=');
if (found != std::string::npos) {
if(found != std::string::npos) {
plugin_name = opt_val.substr(0, found);
filename = opt_val.substr(found + 1, opt_val.size());
}
if (plugin_name == "ic") {
auto *plugin = new iss::plugin::instruction_count(filename);
if(plugin_name == "ic") {
auto* plugin = new iss::plugin::instruction_count(filename);
cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin);
} else if (plugin_name == "ce") {
auto *plugin = new iss::plugin::cycle_estimate(filename);
} else if(plugin_name == "ce") {
auto* plugin = new iss::plugin::cycle_estimate(filename);
cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin);
} else {
@ -288,7 +291,7 @@ void core_complex::before_end_of_elaboration() {
std::array<char const*, 1> a{{filename.c_str()}};
iss::plugin::loader l(plugin_name, {{"initPlugin"}});
auto* plugin = l.call_function<iss::vm_plugin*>("initPlugin", a.size(), a.data());
if(plugin){
if(plugin) {
cpu->vm->register_plugin(*plugin);
plugin_list.push_back(plugin);
} else
@ -297,26 +300,25 @@ void core_complex::before_end_of_elaboration() {
}
}
}
}
void core_complex::start_of_simulation() {
// 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));
string s;
while (getline(is, s, ',')) {
while(getline(is, s, ',')) {
std::pair<uint64_t, bool> start_addr = cpu->load_file(s);
#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);
#else
if (start_addr.second == true)
reset_address=start_addr.first;
if(start_addr.second == true)
reset_address = start_addr.first;
#endif
}
}
if (trc->m_db != nullptr && trc->stream_handle == nullptr) {
if(trc->m_db != nullptr && trc->stream_handle == nullptr) {
string basename(this->name());
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);
@ -324,8 +326,10 @@ void core_complex::start_of_simulation() {
}
bool core_complex::disass_output(uint64_t pc, const std::string instr_str) {
if (trc->m_db == nullptr) return false;
if (trc->tr_handle.is_active()) trc->tr_handle.end_transaction();
if(trc->m_db == nullptr)
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.record_attribute("PC", pc);
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() {
#ifndef CWR_SYSTEMC
set_clock_period(clk_i.read());
set_clock_period(clk_i.read());
#else
set_clock_period(curr_clk.read());
set_clock_period(curr_clk.read());
#endif
}
void core_complex::set_clock_period(sc_core::sc_time period) {
curr_clk = period;
if (period == SC_ZERO_TIME) cpu->set_interrupt_execution(true);
curr_clk = period;
if(period == SC_ZERO_TIME)
cpu->set_interrupt_execution(true);
}
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()); }
@ -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::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()) {
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
do {
wait(SC_ZERO_TIME);
if (rst_i.read()) {
if(rst_i.read()) {
cpu->reset(GET_PROP_VALUE(reset_address));
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());
}
quantum_keeper.reset();
cpu->set_interrupt_execution(false);
cpu->start(dump_ir);
} while (cpu->get_interrupt_execution());
} while(cpu->get_interrupt_execution());
sc_stop();
}
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;
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 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();
std::copy(lut_entry.get_dmi_ptr() + offset, lut_entry.get_dmi_ptr() + offset + length, data);
if(is_fetch)
ibus_inc+=lut_entry.get_read_latency()/curr_clk;
ibus_inc += lut_entry.get_read_latency() / curr_clk;
else
dbus_inc+=lut_entry.get_read_latency()/curr_clk;
dbus_inc += lut_entry.get_read_latency() / curr_clk;
return true;
} else {
auto& sckt = is_fetch? ibus : dbus;
auto& sckt = is_fetch ? ibus : dbus;
tlm::tlm_generic_payload gp;
gp.set_command(tlm::TLM_READ_COMMAND);
gp.set_address(addr);
gp.set_data_ptr(data);
gp.set_data_length(length);
gp.set_streaming_width(length);
sc_time delay=quantum_keeper.get_local_time();
if (trc->m_db != nullptr && trc->tr_handle.is_valid()) {
if (is_fetch && trc->tr_handle.is_active()) {
sc_time delay = quantum_keeper.get_local_time();
if(trc->m_db != nullptr && trc->tr_handle.is_valid()) {
if(is_fetch && trc->tr_handle.is_active()) {
trc->tr_handle.end_transaction();
}
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;
dbus->b_transport(gp, delay);
if(pre_delay>delay) {
if(pre_delay > delay) {
quantum_keeper.reset();
} else {
auto incr = (delay-quantum_keeper.get_local_time())/curr_clk;
auto incr = (delay - quantum_keeper.get_local_time()) / curr_clk;
if(is_fetch)
ibus_inc+=incr;
ibus_inc += incr;
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);
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
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);
if(gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
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_address(addr);
tlm_dmi_ext dmi_data;
if (sckt->get_direct_mem_ptr(gp, dmi_data)) {
if (dmi_data.is_read_allowed())
dmi_lut.addEntry(dmi_data, dmi_data.get_start_address(),
dmi_data.get_end_address() - dmi_data.get_start_address() + 1);
if(sckt->get_direct_mem_ptr(gp, dmi_data)) {
if(dmi_data.is_read_allowed())
dmi_lut.addEntry(dmi_data, dmi_data.get_start_address(), dmi_data.get_end_address() - dmi_data.get_start_address() + 1);
}
}
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);
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();
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;
} else {
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_length(length);
gp.set_streaming_width(length);
sc_time delay=quantum_keeper.get_local_time();
if (trc->m_db != nullptr && trc->tr_handle.is_valid()) {
sc_time delay = quantum_keeper.get_local_time();
if(trc->m_db != nullptr && trc->tr_handle.is_valid()) {
auto preExt = new tlm::scc::scv::tlm_recording_extension(trc->tr_handle, this);
gp.set_extension(preExt);
}
auto pre_delay = delay;
dbus->b_transport(gp, delay);
if(pre_delay>delay)
if(pre_delay > delay)
quantum_keeper.reset();
else
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);
if (gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
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);
if(gp.get_response_status() != tlm::TLM_OK_RESPONSE) {
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_address(addr);
tlm_dmi_ext dmi_data;
if (dbus->get_direct_mem_ptr(gp, dmi_data)) {
if (dmi_data.is_write_allowed())
if(dbus->get_direct_mem_ptr(gp, dmi_data)) {
if(dmi_data.is_write_allowed())
write_lut.addEntry(dmi_data, dmi_data.get_start_address(),
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;
gp.set_command(tlm::TLM_READ_COMMAND);
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;
}
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);
std::copy(data, data + length, write_buf.begin()); // need to copy as TLM does not guarantee data integrity
tlm::tlm_generic_payload gp;

View File

@ -33,10 +33,10 @@
#ifndef _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/traceable.h>
#include <scc/utilities.h>
#include <tlm/scc/initiator_mixin.h>
#include <tlm/scc/scv/tlm_rec_initiator_socket.h>
#ifdef CWR_SYSTEMC
#include <scmlinc/scml_property.h>
@ -45,24 +45,24 @@
#include <cci_configuration>
#define SOCKET_WIDTH scc::LT
#endif
#include <memory>
#include <tlm>
#include <tlm_utils/tlm_quantumkeeper.h>
#include <util/range_lut.h>
#include <memory>
namespace iss {
class vm_plugin;
class vm_plugin;
}
namespace sysc {
class tlm_dmi_ext : public tlm::tlm_dmi {
public:
bool operator==(const tlm_dmi_ext &o) const {
return this->get_granted_access() == o.get_granted_access() &&
this->get_start_address() == o.get_start_address() && this->get_end_address() == o.get_end_address();
bool operator==(const tlm_dmi_ext& o) const {
return this->get_granted_access() == o.get_granted_access() && this->get_start_address() == o.get_start_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 {
@ -86,7 +86,7 @@ public:
sc_core::sc_vector<sc_core::sc_in<bool>> local_irq_i{"local_irq_i", 16};
#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"};
@ -113,11 +113,11 @@ public:
core_complex(sc_core::sc_module_name const& name);
#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};
@ -151,49 +151,48 @@ public:
, plugins{"plugins", ""}
, fetch_lut(tlm_dmi_ext())
, read_lut(tlm_dmi_ext())
, write_lut(tlm_dmi_ext())
{
init();
, write_lut(tlm_dmi_ext()) {
init();
}
#endif
~core_complex();
inline unsigned get_last_bus_cycles() {
auto mem_incr = std::max(ibus_inc, dbus_inc);
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) {
auto core_inc = curr_clk * (cycle - last_sync_cycle);
quantum_keeper.inc(core_inc);
if (quantum_keeper.need_sync()) {
if(quantum_keeper.need_sync()) {
wait(quantum_keeper.get_local_time());
quantum_keeper.reset();
}
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);
void set_clock_period(sc_core::sc_time period);
protected:
void before_end_of_elaboration() override;
void start_of_simulation() override;
void forward();
void forward();
void run();
void rst_cb();
void sw_irq_cb();
@ -209,10 +208,10 @@ protected:
uint64_t ibus_inc{0}, dbus_inc{0};
core_trace* trc{nullptr};
std::unique_ptr<scc::tick2time> t2t;
private:
void init();
std::vector<iss::vm_plugin *> plugin_list;
std::vector<iss::vm_plugin*> plugin_list;
};
} /* namespace tgfs */
} /* namespace sysc */

View File

@ -33,56 +33,58 @@
#ifndef _ISS_FACTORY_H_
#define _ISS_FACTORY_H_
#include <iss/iss.h>
#include "sc_core_adapter_if.h"
#include <memory>
#include <unordered_map>
#include <functional>
#include <string>
#include <algorithm>
#include <functional>
#include <iss/iss.h>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
namespace sysc {
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 {
public:
using base_t = std::tuple<sc_cpu_ptr, vm_ptr>;
using create_fn = std::function<base_t(unsigned, void*) >;
using registry_t = std::unordered_map<std::string, create_fn> ;
using create_fn = std::function<base_t(unsigned, void*)>;
using registry_t = std::unordered_map<std::string, create_fn>;
iss_factory() = default;
iss_factory(const iss_factory &) = delete;
iss_factory & operator=(const iss_factory &) = delete;
iss_factory(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;
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);
if (regEntry != registry.end())
if(regEntry != registry.end())
return regEntry->second(gdb_port, init_data);
return {nullptr, nullptr};
}
std::vector<std::string> get_names() {
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){
return p.first;
});
std::transform(std::begin(registry), std::end(registry), std::begin(keys),
[](std::pair<std::string, create_fn> const& p) { return p.first; });
return keys;
}
private:
registry_t registry;
};
}
} // namespace sysc
#endif /* _ISS_FACTORY_H_ */

View File

@ -30,79 +30,79 @@
*
*******************************************************************************/
#include "core_complex.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_mu_p.h>
#include "sc_core_adapter.h"
#include "core_complex.h"
#include <array>
#include <iss/arch/tgc5c.h>
namespace iss {
namespace interp {
using namespace sysc;
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 {
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
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);
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)}};
})
};
}
iss_factory::instance().register_creator("tgc5c|m_p|interp",
[](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
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);
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)
namespace llvm {
using namespace sysc;
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 {
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
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);
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)}};
})
};
}
iss_factory::instance().register_creator("tgc5c|m_p|llvm",
[](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
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);
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
#if defined(WITH_TCC)
namespace tcc {
using namespace sysc;
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 {
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
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);
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)}};
})
};
}
iss_factory::instance().register_creator("tgc5c|m_p|tcc",
[](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
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);
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
#if defined(WITH_ASMJIT)
namespace asmjit {
using namespace sysc;
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 {
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
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);
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)}};
})
};
}
iss_factory::instance().register_creator("tgc5c|m_p|asmjit",
[](unsigned gdb_port, void* data) -> iss_factory::base_t {
auto cc = reinterpret_cast<sysc::tgfs::core_complex*>(data);
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);
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
}
} // namespace iss

View File

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

View File

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

View File

@ -1,26 +1,41 @@
x86::Mem get_reg_ptr(jit_holder& jh, unsigned idx){
x86::Gp tmp_ptr = jh.cc.newUIntPtr("tmp_ptr");
jh.cc.mov(tmp_ptr, jh.regs_base_ptr);
jh.cc.add(tmp_ptr, traits::reg_byte_offsets[idx]);
switch(traits::reg_bit_widths[idx]){
case 8:
return x86::ptr_8(tmp_ptr);
case 16:
return x86::ptr_16(tmp_ptr);
case 32:
return x86::ptr_32(tmp_ptr);
case 64:
return x86::ptr_64(tmp_ptr);
default:
throw std::runtime_error("Invalid reg size in get_reg_ptr");
}
x86::Mem get_reg_ptr(jit_holder& jh, unsigned idx) {
x86::Gp tmp_ptr = jh.cc.newUIntPtr("tmp_ptr");
jh.cc.mov(tmp_ptr, jh.regs_base_ptr);
jh.cc.add(tmp_ptr, traits::reg_byte_offsets[idx]);
switch(traits::reg_bit_widths[idx]) {
case 8:
return x86::ptr_8(tmp_ptr);
case 16:
return x86::ptr_16(tmp_ptr);
case 32:
return x86::ptr_32(tmp_ptr);
case 64:
return x86::ptr_64(tmp_ptr);
default:
throw std::runtime_error("Invalid reg size in get_reg_ptr");
}
}
x86::Gp get_reg_for(jit_holder& jh, unsigned idx){
//can check for regs in jh and return them instead of creating new ones
switch(traits::reg_bit_widths[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
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:
return jh.cc.newInt8();
case 16:
@ -32,23 +47,8 @@ x86::Gp get_reg_for(jit_holder& jh, unsigned idx){
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:
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
switch(size){
switch(size) {
case 8:
return jh.cc.newUInt8();
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");
}
}
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 reg = get_reg_for(jh, idx);
jh.cc.mov(reg, ptr);
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);
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;
cc.comment("\n//(*icount)++;");
@ -83,33 +83,30 @@ void gen_instr_prologue(jit_holder& jh, addr_t pc){
cc.comment("\n//*trap_state=*pending_trap;");
cc.mov(get_reg_ptr(jh, traits::PENDING_TRAP), jh.trap_state);
cc.comment("\n//increment *next_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;
cc.comment("\n//if(*trap_state!=0) goto trap_entry;");
cc.test(jh.trap_state, jh.trap_state);
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");
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.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.next_pc = load_reg_from_mem(jh, traits::NEXT_PC);
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;
cc.comment("\n//return *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.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));
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");
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(3, instr);
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.ret(jh.next_pc);
}
// TODO implement
}
//TODO implement
void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) { 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"); }
void gen_raise(jit_holder& jh, uint16_t trap_id, uint16_t cause) {
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};
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>>
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;
switch (op) {
case add: { cc.add(a, b); break; }
case sub: { cc.sub(a, b); break; }
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));
switch(op) {
case add: {
cc.add(a, b);
break;
}
case sub: {
cc.sub(a, b);
break;
}
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;
}
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;
switch (op) {
case imul: {
x86::Gp dummy = cc.newInt64();
cc.imul(dummy, a.r64(), b.r64());
return a;
}
case mul: {
x86::Gp dummy = cc.newInt64();
cc.mul(dummy, a.r64(), b.r64());
return a;
}
case idiv: {
x86::Gp dummy = cc.newInt64();
cc.mov(dummy, 0);
cc.idiv(dummy, a.r64(), b.r64());
return a;
}
case div: {
x86::Gp dummy = cc.newInt64();
cc.mov(dummy, 0);
cc.div(dummy, a.r64(), b.r64());
return a;
}
case srem:{
x86::Gp rem = cc.newInt32();
cc.mov(rem, 0);
auto a_reg = cc.newInt32();
cc.mov(a_reg, a.r32());
cc.idiv(rem, a_reg, b.r32());
return rem;
}
case urem:{
x86::Gp rem = cc.newInt32();
cc.mov(rem, 0);
auto a_reg = cc.newInt32();
cc.mov(a_reg, a.r32());
cc.div(rem, a_reg, b.r32());
return rem;
}
switch(op) {
case imul: {
x86::Gp dummy = cc.newInt64();
cc.imul(dummy, a.r64(), b.r64());
return a;
}
case mul: {
x86::Gp dummy = cc.newInt64();
cc.mul(dummy, a.r64(), b.r64());
return a;
}
case idiv: {
x86::Gp dummy = cc.newInt64();
cc.mov(dummy, 0);
cc.idiv(dummy, a.r64(), b.r64());
return a;
}
case div: {
x86::Gp dummy = cc.newInt64();
cc.mov(dummy, 0);
cc.div(dummy, a.r64(), b.r64());
return a;
}
case srem: {
x86::Gp rem = cc.newInt32();
cc.mov(rem, 0);
auto a_reg = cc.newInt32();
cc.mov(a_reg, a.r32());
cc.idiv(rem, a_reg, b.r32());
return rem;
}
case urem: {
x86::Gp rem = cc.newInt32();
cc.mov(rem, 0);
auto a_reg = cc.newInt32();
cc.mov(a_reg, a.r32());
cc.div(rem, a_reg, b.r32());
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;
}
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();
/* switch(a.size()){
case 1: b_reg = jh.cc.newInt8(); break;
case 2: b_reg = jh.cc.newInt16(); break;
case 4: b_reg = jh.cc.newInt32(); break;
case 8: b_reg = jh.cc.newInt64(); break;
default: throw std::runtime_error(fmt::format("Invalid size ({}) in gen operation", a.size()));
} */
/* switch(a.size()){
case 1: b_reg = jh.cc.newInt8(); break;
case 2: b_reg = jh.cc.newInt16(); break;
case 4: b_reg = jh.cc.newInt32(); break;
case 8: b_reg = jh.cc.newInt64(); break;
default: throw std::runtime_error(fmt::format("Invalid size ({}) in gen operation", a.size()));
} */
jh.cc.mov(b_reg, b);
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>>
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::Gp tmp = cc.newInt8();
cc.mov(tmp,1);
cc.mov(tmp, 1);
Label label_then = cc.newLabel();
cc.cmp(a,b);
switch (op) {
case eq: cc.je(label_then); break;
case ne: cc.jne(label_then); break;
case lt: cc.jl(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;
cc.cmp(a, b);
switch(op) {
case eq:
cc.je(label_then);
break;
case ne:
cc.jne(label_then);
break;
case lt:
cc.jl(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: {
Label label_false = cc.newLabel();
cc.cmp(a, 0);
@ -267,78 +303,103 @@ x86::Gp gen_operation(jit_holder& jh, comparison_operation op, x86::Gp a, T b){
auto b_reg = cc.newInt8();
cc.mov(b_reg, b);
cc.cmp(b_reg, 0);
cc.jne(label_then);
cc.jne(label_then);
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);
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;
switch (op) {
case lnot: throw std::runtime_error("Current operation not supported in gen_operation(lnot)");
case inc: { cc.inc(a); break; }
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));
switch(op) {
case lnot:
throw std::runtime_error("Current operation not supported in gen_operation(lnot)");
case inc: {
cc.inc(a);
break;
}
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;
}
/* 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 {
auto val_reg = get_reg_for(jh, sizeof(val)*8);
auto tmp = get_reg_for(jh, size);
jh.cc.mov(val_reg, val);
if(is_signed) jh.cc.movsx(tmp, val_reg);
else jh.cc.movzx(tmp,val_reg);
return tmp;
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 { auto val_reg = get_reg_for(jh, sizeof(val)*8); auto tmp = get_reg_for(jh, size); 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>
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 {
auto val_reg = get_reg_for(jh, sizeof(val)*8);
auto tmp = get_reg_for(jh, size);
jh.cc.mov(val_reg, val);
if(is_signed) jh.cc.movsx(tmp, val_reg);
else jh.cc.movzx(tmp,val_reg);
return tmp;
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 { auto val_reg = get_reg_for(jh, sizeof(val)*8); auto tmp = get_reg_for(jh, size); 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>>
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);
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) {
auto& cc = jh.cc;
if(is_signed){
switch(val.size()){
case 1: cc.cbw(val); break;
case 2: cc.cwde(val); break;
case 4: cc.cdqe(val); break;
case 8: break;
default: throw std::runtime_error("Invalid register size in gen_ext");
if(is_signed) {
switch(val.size()) {
case 1:
cc.cbw(val);
break;
case 2:
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){
case 8: cc.and_(val,std::numeric_limits<uint8_t>::max()); return val.r8();
case 16: cc.and_(val,std::numeric_limits<uint16_t>::max()); 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");
switch(size) {
case 8:
cc.and_(val, std::numeric_limits<uint8_t>::max());
return val.r8();
case 16:
cc.and_(val, std::numeric_limits<uint16_t>::max());
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;
auto ret_reg = cc.newInt32();
@ -347,7 +408,7 @@ inline x86::Gp gen_read_mem(jit_holder& jh, mem_type_e type, x86::Gp addr, uint3
auto space_reg = cc.newInt32();
cc.mov(space_reg, static_cast<uint16_t>(iss::address_type::VIRTUAL));
auto val_ptr = cc.newUIntPtr();
cc.mov(val_ptr, read_mem_buf);
@ -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;
x86::Gp val_reg = cc.newInt64();
switch(length){
case 1:{
switch(length) {
case 1: {
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();
break;
}
case 2:{
case 2: {
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();
break;
}
case 4:{
case 4: {
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();
break;
}
case 8:{
case 8: {
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();
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);
@ -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.and_(val_reg, mask);
cc.cmp(ret_reg,0);
cc.cmp(ret_reg, 0);
cc.jne(jh.trap_entry);
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;
auto length_ptr = jh.cc.newIntPtr();
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);
}
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();
jh.cc.mov(addr_reg, addr);
jh.cc.mov(addr_reg, addr);
uint32_t length_val = 0;
auto length_ptr = jh.cc.newIntPtr();
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);
}
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();
jh.cc.mov(addr_reg, addr);
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();
jh.cc.mov(val_reg, val);
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;
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();
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>());
}
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>());
}
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>());
}
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>());
}
else throw std::runtime_error("Invalid register size in gen_write_mem");
} else
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(1, space_reg);
invokeNode->setArg(2, mem_type_reg);
invokeNode->setArg(3, addr);
invokeNode->setArg(4, val);
cc.cmp(ret_reg,0);
cc.cmp(ret_reg, 0);
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();
jh.cc.mov(addr_reg, addr);
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();
jh.cc.mov(val_reg, val);
auto addr_reg = jh.cc.newInt64();
jh.cc.mov(addr_reg, addr);
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"
extern "C" {
#include <softfloat.h>
#include "internals.h"
#include "specialize.h"
#include <softfloat.h>
}
#include <limits>
using this_t = uint8_t *;
using this_t = uint8_t*;
const uint8_t rmm_map[] = {
softfloat_round_near_even /*RNE*/,
softfloat_round_minMag/*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*/,
softfloat_round_near_even /*RNE*/, softfloat_round_minMag /*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" {
uint32_t fget_flags(){
return softfloat_exceptionFlags&0x1f;
}
uint32_t fget_flags() { return softfloat_exceptionFlags & 0x1f; }
uint32_t fadd_s(uint32_t v1, uint32_t v2, uint8_t mode) {
float32_t v1f{v1},v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float32_t r =f32_add(v1f, v2f);
float32_t v1f{v1}, v2f{v2};
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float32_t r = f32_add(v1f, v2f);
return r.v;
}
uint32_t fsub_s(uint32_t v1, uint32_t v2, uint8_t mode) {
float32_t v1f{v1},v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float32_t r=f32_sub(v1f, v2f);
float32_t v1f{v1}, v2f{v2};
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float32_t r = f32_sub(v1f, v2f);
return r.v;
}
uint32_t fmul_s(uint32_t v1, uint32_t v2, uint8_t mode) {
float32_t v1f{v1},v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float32_t r=f32_mul(v1f, v2f);
float32_t v1f{v1}, v2f{v2};
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float32_t r = f32_mul(v1f, v2f);
return r.v;
}
uint32_t fdiv_s(uint32_t v1, uint32_t v2, uint8_t mode) {
float32_t v1f{v1},v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float32_t r=f32_div(v1f, v2f);
float32_t v1f{v1}, v2f{v2};
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float32_t r = f32_div(v1f, v2f);
return r.v;
}
uint32_t fsqrt_s(uint32_t v1, uint8_t mode) {
float32_t v1f{v1};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float32_t r=f32_sqrt(v1f);
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float32_t r = f32_sqrt(v1f);
return r.v;
}
uint32_t fcmp_s(uint32_t v1, uint32_t v2, uint32_t op) {
float32_t v1f{v1},v2f{v2};
softfloat_exceptionFlags=0;
bool nan = (v1&defaultNaNF32UI)==quiet_nan32 || (v2&defaultNaNF32UI)==quiet_nan32;
float32_t v1f{v1}, v2f{v2};
softfloat_exceptionFlags = 0;
bool nan = (v1 & defaultNaNF32UI) == quiet_nan32 || (v2 & defaultNaNF32UI) == quiet_nan32;
bool snan = softfloat_isSigNaNF32UI(v1) || softfloat_isSigNaNF32UI(v2);
switch(op){
switch(op) {
case 0:
if(nan | snan){
if(snan) softfloat_raiseFlags(softfloat_flag_invalid);
if(nan | snan) {
if(snan)
softfloat_raiseFlags(softfloat_flag_invalid);
return 0;
} else
return f32_eq(v1f,v2f )?1:0;
return f32_eq(v1f, v2f) ? 1 : 0;
case 1:
if(nan | snan){
if(nan | snan) {
softfloat_raiseFlags(softfloat_flag_invalid);
return 0;
} else
return f32_le(v1f,v2f )?1:0;
return f32_le(v1f, v2f) ? 1 : 0;
case 2:
if(nan | snan){
if(nan | snan) {
softfloat_raiseFlags(softfloat_flag_invalid);
return 0;
} else
return f32_lt(v1f,v2f )?1:0;
return f32_lt(v1f, v2f) ? 1 : 0;
default:
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) {
float32_t v1f{v1};
softfloat_exceptionFlags=0;
softfloat_exceptionFlags = 0;
float32_t r;
switch(op){
case 0:{ //w->s, fp to int32
uint_fast32_t res = f32_to_i32(v1f,rmm_map[mode&0x7],true);
switch(op) {
case 0: { // w->s, fp to int32
uint_fast32_t res = f32_to_i32(v1f, rmm_map[mode & 0x7], true);
return (uint32_t)res;
}
case 1:{ //wu->s
uint_fast32_t res = f32_to_ui32(v1f,rmm_map[mode&0x7],true);
case 1: { // wu->s
uint_fast32_t res = f32_to_ui32(v1f, rmm_map[mode & 0x7], true);
return (uint32_t)res;
}
case 2: //s->w
r=i32_to_f32(v1);
case 2: // s->w
r = i32_to_f32(v1);
return r.v;
case 3: //s->wu
r=ui32_to_f32(v1);
case 3: // s->wu
r = ui32_to_f32(v1);
return r.v;
}
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) {
// op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)}
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float32_t res = softfloat_mulAddF32(v1, v2, v3, op&0x1);
if(op>1) res.v ^= 1ULL<<31;
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float32_t res = softfloat_mulAddF32(v1, v2, v3, op & 0x1);
if(op > 1)
res.v ^= 1ULL << 31;
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 v1_snan = softfloat_isSigNaNF32UI(v1);
bool v2_snan = softfloat_isSigNaNF32UI(v2);
if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid);
if (v1_nan || v1_snan)
if(v1_snan || v2_snan)
softfloat_raiseFlags(softfloat_flag_invalid);
if(v1_nan || v1_snan)
return (v2_nan || v2_snan) ? defaultNaNF32UI : v2;
else
if (v2_nan || v2_snan)
return v1;
else {
if ((v1 & 0x7fffffff) == 0 && (v2 & 0x7fffffff) == 0) {
return op == 0 ? ((v1 & 0x80000000) ? v1 : v2) : ((v1 & 0x80000000) ? v2 : v1);
} else {
float32_t v1f{ v1 }, v2f{ v2 };
return op == 0 ? (f32_lt(v1f, v2f) ? v1 : v2) : (f32_lt(v1f, v2f) ? v2 : v1);
}
else if(v2_nan || v2_snan)
return v1;
else {
if((v1 & 0x7fffffff) == 0 && (v2 & 0x7fffffff) == 0) {
return op == 0 ? ((v1 & 0x80000000) ? v1 : v2) : ((v1 & 0x80000000) ? v2 : v1);
} else {
float32_t v1f{v1}, v2f{v2};
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};
union ui32_f32 uA;
@ -195,30 +189,23 @@ uint32_t fclass_s( uint32_t v1 ){
uA.f = a;
uiA = uA.ui;
uint_fast16_t infOrNaN = expF32UI( uiA ) == 0xFF;
uint_fast16_t subnormalOrZero = expF32UI( uiA ) == 0;
bool sign = signF32UI( uiA );
bool fracZero = fracF32UI( uiA ) == 0;
bool isNaN = isNaNF32UI( uiA );
bool isSNaN = softfloat_isSigNaNF32UI( uiA );
uint_fast16_t infOrNaN = expF32UI(uiA) == 0xFF;
uint_fast16_t subnormalOrZero = expF32UI(uiA) == 0;
bool sign = signF32UI(uiA);
bool fracZero = fracF32UI(uiA) == 0;
bool isNaN = isNaNF32UI(uiA);
bool isSNaN = softfloat_isSigNaNF32UI(uiA);
return
( sign && infOrNaN && fracZero ) << 0 |
( sign && !infOrNaN && !subnormalOrZero ) << 1 |
( sign && subnormalOrZero && !fracZero ) << 2 |
( 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;
return (sign && infOrNaN && fracZero) << 0 | (sign && !infOrNaN && !subnormalOrZero) << 1 |
(sign && subnormalOrZero && !fracZero) << 2 | (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){
softfloat_roundingMode=rmm_map[mode&0x7];
bool nan = (v1 & defaultNaNF64UI)==defaultNaNF64UI;
if(nan){
uint32_t fconv_d2f(uint64_t v1, uint8_t mode) {
softfloat_roundingMode = rmm_map[mode & 0x7];
bool nan = (v1 & defaultNaNF64UI) == defaultNaNF64UI;
if(nan) {
return defaultNaNF32UI;
} else {
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){
bool nan = (v1 & defaultNaNF32UI)==defaultNaNF32UI;
if(nan){
uint64_t fconv_f2d(uint32_t v1, uint8_t mode) {
bool nan = (v1 & defaultNaNF32UI) == defaultNaNF32UI;
if(nan) {
return defaultNaNF64UI;
} else {
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_roundingMode = rmm_map[mode & 0x7];
float64_t res = f32_to_f64(float32_t{v1});
return res.v;
}
}
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);
float64_t v1f{v1},v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float64_t r =f64_add(v1f, v2f);
float64_t v1f{v1}, v2f{v2};
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float64_t r = f64_add(v1f, v2f);
return r.v;
}
uint64_t fsub_d(uint64_t v1, uint64_t v2, uint8_t mode) {
float64_t v1f{v1},v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float64_t r=f64_sub(v1f, v2f);
float64_t v1f{v1}, v2f{v2};
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float64_t r = f64_sub(v1f, v2f);
return r.v;
}
uint64_t fmul_d(uint64_t v1, uint64_t v2, uint8_t mode) {
float64_t v1f{v1},v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float64_t r=f64_mul(v1f, v2f);
float64_t v1f{v1}, v2f{v2};
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float64_t r = f64_mul(v1f, v2f);
return r.v;
}
uint64_t fdiv_d(uint64_t v1, uint64_t v2, uint8_t mode) {
float64_t v1f{v1},v2f{v2};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float64_t r=f64_div(v1f, v2f);
float64_t v1f{v1}, v2f{v2};
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float64_t r = f64_div(v1f, v2f);
return r.v;
}
uint64_t fsqrt_d(uint64_t v1, uint8_t mode) {
float64_t v1f{v1};
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float64_t r=f64_sqrt(v1f);
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float64_t r = f64_sqrt(v1f);
return r.v;
}
uint64_t fcmp_d(uint64_t v1, uint64_t v2, uint32_t op) {
float64_t v1f{v1},v2f{v2};
softfloat_exceptionFlags=0;
bool nan = (v1&defaultNaNF64UI)==quiet_nan32 || (v2&defaultNaNF64UI)==quiet_nan32;
float64_t v1f{v1}, v2f{v2};
softfloat_exceptionFlags = 0;
bool nan = (v1 & defaultNaNF64UI) == quiet_nan32 || (v2 & defaultNaNF64UI) == quiet_nan32;
bool snan = softfloat_isSigNaNF64UI(v1) || softfloat_isSigNaNF64UI(v2);
switch(op){
switch(op) {
case 0:
if(nan | snan){
if(snan) softfloat_raiseFlags(softfloat_flag_invalid);
if(nan | snan) {
if(snan)
softfloat_raiseFlags(softfloat_flag_invalid);
return 0;
} else
return f64_eq(v1f,v2f )?1:0;
return f64_eq(v1f, v2f) ? 1 : 0;
case 1:
if(nan | snan){
if(nan | snan) {
softfloat_raiseFlags(softfloat_flag_invalid);
return 0;
} else
return f64_le(v1f,v2f )?1:0;
return f64_le(v1f, v2f) ? 1 : 0;
case 2:
if(nan | snan){
if(nan | snan) {
softfloat_raiseFlags(softfloat_flag_invalid);
return 0;
} else
return f64_lt(v1f,v2f )?1:0;
return f64_lt(v1f, v2f) ? 1 : 0;
default:
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) {
float64_t v1f{v1};
softfloat_exceptionFlags=0;
softfloat_exceptionFlags = 0;
float64_t r;
switch(op){
case 0:{ //l->d, fp to int32
int64_t res = f64_to_i64(v1f,rmm_map[mode&0x7],true);
switch(op) {
case 0: { // l->d, fp to int32
int64_t res = f64_to_i64(v1f, rmm_map[mode & 0x7], true);
return (uint64_t)res;
}
case 1:{ //lu->s
uint64_t res = f64_to_ui64(v1f,rmm_map[mode&0x7],true);
case 1: { // lu->s
uint64_t res = f64_to_ui64(v1f, rmm_map[mode & 0x7], true);
return res;
}
case 2: //s->l
r=i64_to_f64(v1);
case 2: // s->l
r = i64_to_f64(v1);
return r.v;
case 3: //s->lu
r=ui64_to_f64(v1);
case 3: // s->lu
r = ui64_to_f64(v1);
return r.v;
}
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) {
// op should be {softfloat_mulAdd_subProd(2), softfloat_mulAdd_subC(1)}
softfloat_roundingMode=rmm_map[mode&0x7];
softfloat_exceptionFlags=0;
float64_t res = softfloat_mulAddF64(v1, v2, v3, op&0x1);
if(op>1) res.v ^= 1ULL<<63;
softfloat_roundingMode = rmm_map[mode & 0x7];
softfloat_exceptionFlags = 0;
float64_t res = softfloat_mulAddF64(v1, v2, v3, op & 0x1);
if(op > 1)
res.v ^= 1ULL << 63;
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 v1_snan = softfloat_isSigNaNF64UI(v1);
bool v2_snan = softfloat_isSigNaNF64UI(v2);
if (v1_snan || v2_snan) softfloat_raiseFlags(softfloat_flag_invalid);
if (v1_nan || v1_snan)
if(v1_snan || v2_snan)
softfloat_raiseFlags(softfloat_flag_invalid);
if(v1_nan || v1_snan)
return (v2_nan || v2_snan) ? defaultNaNF64UI : v2;
else
if (v2_nan || v2_snan)
return v1;
else {
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) :
((v1 & std::numeric_limits<int64_t>::min()) ? v2 : v1);
} else {
float64_t v1f{ v1 }, v2f{ v2 };
return op == 0 ?
(f64_lt(v1f, v2f) ? v1 : v2) :
(f64_lt(v1f, v2f) ? v2 : v1);
}
else if(v2_nan || v2_snan)
return v1;
else {
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)
: ((v1 & std::numeric_limits<int64_t>::min()) ? v2 : v1);
} else {
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};
union ui64_f64 uA;
@ -376,68 +362,61 @@ uint64_t fclass_d(uint64_t v1 ){
uA.f = a;
uiA = uA.ui;
uint_fast16_t infOrNaN = expF64UI( uiA ) == 0x7FF;
uint_fast16_t subnormalOrZero = expF64UI( uiA ) == 0;
bool sign = signF64UI( uiA );
bool fracZero = fracF64UI( uiA ) == 0;
bool isNaN = isNaNF64UI( uiA );
bool isSNaN = softfloat_isSigNaNF64UI( uiA );
uint_fast16_t infOrNaN = expF64UI(uiA) == 0x7FF;
uint_fast16_t subnormalOrZero = expF64UI(uiA) == 0;
bool sign = signF64UI(uiA);
bool fracZero = fracF64UI(uiA) == 0;
bool isNaN = isNaNF64UI(uiA);
bool isSNaN = softfloat_isSigNaNF64UI(uiA);
return
( sign && infOrNaN && fracZero ) << 0 |
( sign && !infOrNaN && !subnormalOrZero ) << 1 |
( sign && subnormalOrZero && !fracZero ) << 2 |
( 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;
return (sign && infOrNaN && fracZero) << 0 | (sign && !infOrNaN && !subnormalOrZero) << 1 |
(sign && subnormalOrZero && !fracZero) << 2 | (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) {
float32_t v1f{v1};
softfloat_exceptionFlags=0;
softfloat_exceptionFlags = 0;
float64_t r;
switch(op){
case 0: //l->s, fp to int32
return f32_to_i64(v1f,rmm_map[mode&0x7],true);
case 1: //wu->s
return f32_to_ui64(v1f,rmm_map[mode&0x7],true);
case 2: //s->w
r=i32_to_f64(v1);
switch(op) {
case 0: // l->s, fp to int32
return f32_to_i64(v1f, rmm_map[mode & 0x7], true);
case 1: // wu->s
return f32_to_ui64(v1f, rmm_map[mode & 0x7], true);
case 2: // s->w
r = i32_to_f64(v1);
return r.v;
case 3: //s->wu
r=ui32_to_f64(v1);
case 3: // s->wu
r = ui32_to_f64(v1);
return r.v;
}
return 0;
}
uint32_t fcvt_64_32(uint64_t v1, uint32_t op, uint8_t mode) {
softfloat_exceptionFlags=0;
softfloat_exceptionFlags = 0;
float32_t r;
switch(op){
case 0:{ //wu->s
int32_t r=f64_to_i32(float64_t{v1}, rmm_map[mode&0x7],true);
switch(op) {
case 0: { // wu->s
int32_t r = f64_to_i32(float64_t{v1}, rmm_map[mode & 0x7], true);
return r;
}
case 1:{ //wu->s
uint32_t r=f64_to_ui32(float64_t{v1}, rmm_map[mode&0x7],true);
case 1: { // wu->s
uint32_t r = f64_to_ui32(float64_t{v1}, rmm_map[mode & 0x7], true);
return r;
}
case 2: //l->s, fp to int32
r=i64_to_f32(v1);
case 2: // l->s, fp to int32
r = i64_to_f32(v1);
return r.v;
case 3: //wu->s
r=ui64_to_f32(v1);
case 3: // wu->s
r = ui64_to_f32(v1);
return r.v;
}
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());
if((v & mask) != mask)
return 0x7fc00000;
@ -445,4 +424,3 @@ uint32_t unbox_s(uint64_t v){
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 fdiv_s(uint32_t v1, uint32_t v2, 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 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 fclass_s( uint32_t v1 );
uint32_t fclass_s(uint32_t v1);
uint32_t fconv_d2f(uint64_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);
@ -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 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 fsel_d(uint64_t v1, uint64_t v2, uint32_t op) ;
uint64_t fclass_d(uint64_t v1 );
uint64_t fsel_d(uint64_t v1, uint64_t v2, uint32_t op);
uint64_t fclass_d(uint64_t v1);
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 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>
extern "C" {
#include <softfloat.h>
#include "internals.h"
#include "specialize.h"
#include <softfloat.h>
}
#include <limits>
@ -50,60 +50,58 @@ namespace fp_impl {
using namespace std;
using namespace ::llvm;
#define INT_TYPE(L) Type::getIntNTy(mod->getContext(), L)
#define FLOAT_TYPE Type::getFloatTy(mod->getContext())
#define DOUBLE_TYPE Type::getDoubleTy(mod->getContext())
#define VOID_TYPE Type::getVoidTy(mod->getContext())
#define INT_TYPE(L) Type::getIntNTy(mod->getContext(), L)
#define FLOAT_TYPE Type::getFloatTy(mod->getContext())
#define DOUBLE_TYPE Type::getDoubleTy(mod->getContext())
#define VOID_TYPE Type::getVoidTy(mod->getContext())
#define THIS_PTR_TYPE Type::getIntNPtrTy(mod->getContext(), 8)
#define FDECLL(NAME, RET, ...) \
Function *NAME##_func = CurrentModule->getFunction(#NAME); \
if (!NAME##_func) { \
std::vector<Type *> NAME##_args{__VA_ARGS__}; \
FunctionType *NAME##_type = FunctionType::get(RET, NAME##_args, false); \
NAME##_func = Function::Create(NAME##_type, GlobalValue::ExternalLinkage, #NAME, CurrentModule); \
NAME##_func->setCallingConv(CallingConv::C); \
#define FDECLL(NAME, RET, ...) \
Function* NAME##_func = CurrentModule->getFunction(#NAME); \
if(!NAME##_func) { \
std::vector<Type*> NAME##_args{__VA_ARGS__}; \
FunctionType* NAME##_type = FunctionType::get(RET, NAME##_args, false); \
NAME##_func = Function::Create(NAME##_type, GlobalValue::ExternalLinkage, #NAME, CurrentModule); \
NAME##_func->setCallingConv(CallingConv::C); \
}
#define FDECL(NAME, RET, ...) \
std::vector<Type *> NAME##_args{__VA_ARGS__}; \
FunctionType *NAME##_type = FunctionType::get(RET, NAME##_args, false); \
#define FDECL(NAME, RET, ...) \
std::vector<Type*> NAME##_args{__VA_ARGS__}; \
FunctionType* NAME##_type = FunctionType::get(RET, NAME##_args, false); \
mod->getOrInsertFunction(#NAME, NAME##_type);
void add_fp_functions_2_module(Module *mod, uint32_t flen, uint32_t xlen) {
if(flen){
void add_fp_functions_2_module(Module* mod, uint32_t flen, uint32_t xlen) {
if(flen) {
FDECL(fget_flags, INT_TYPE(32));
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(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(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(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(fsel_s, INT_TYPE(32), INT_TYPE(32), 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_64_32, INT_TYPE(32), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
if(flen>32){
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(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(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(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(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(fsel_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32));
FDECL(fclass_d, INT_TYPE(64), INT_TYPE(64));
FDECL(unbox_s, INT_TYPE(32), INT_TYPE(64));
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(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(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(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(fsel_s, INT_TYPE(32), INT_TYPE(32), 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_64_32, INT_TYPE(32), INT_TYPE(64), INT_TYPE(32), INT_TYPE(8));
if(flen > 32) {
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(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(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(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(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(fsel_d, INT_TYPE(64), INT_TYPE(64), INT_TYPE(64), INT_TYPE(32));
FDECL(fclass_d, INT_TYPE(64), 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