Add wasm tacle-bench targets

This commit is contained in:
2026-06-12 20:06:22 +02:00
parent 30daa8a00c
commit 08c2e9c13d
1122 changed files with 520422 additions and 0 deletions

View File

@ -0,0 +1,25 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(binarysearch)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/binarysearch.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/binarysearch.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,42 @@
File: binarysearch.c
Original provenience: Mälardalen benchmark suite,
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bs
2015-10-10:
- Removed original header comment, replaced by TACLeBench header.
- Added prefix "binarysearch_" to all global symbols.
- Added explicit forward declarations of functions, removed obsolete forward
declaration of function binary_search.
- Replaced initialization of global array "binarysearch_data" by
TACLeBench-compliant initialization code.
- Added new global variable "binarysearch_result" to store the found return
value.
- Added new function binarysearch_return producing the searched data element as
return value.
- Removed global variable "binarysearch_cnt1" that was used for profiling.
- Added new function binarysearch_main according to TACLeBench guidelines.
binarysearch_main is annotated as entry-point for timing analysis.
- Corrected flow fact in function "binarysearch_binary_search" to cover the
interval [1, 4] instead of [4, 4].
- Applied code formatting according to the following rules
- Lines shall not be wider than 80 characters; whenever possible, appropriate
line breaks shall be inserted to keep lines below 80 characters
- Indentation is done using whitespaces only, no tabs. Code is indented by
two whitespaces
- Two empty lines are put between any two functions
- In non-empty lists or index expressions, opening '(' and '[' are followed by
one whitespace, closing ')' and ']' are preceded by one whitespace
- In comma- or colon-separated argument lists, one whitespace is put after
each comma/colon
- Names of functions and global variables all start with a benchmark-specific
prefix (here: binarysearch_) followed by lowercase letter (e.g.,
binarysearch_square)
- For pointer types, one whitespace is put before the '*'
- Operators within expressions shall be preceded and followed by one
whitespace
- Code of then- and else-parts of if-then-else statements shall be put in
separate lines, not in the same lines as the if-condition or the keyword
"else"
- Opening braces '{' denoting the beginning of code for some if-else or loop
body shall be put at the end of the same line where the keywords "if",
"else", "for", "while" etc. occur

View File

@ -0,0 +1,156 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: binarysearch
Author: Sung-Soo Lim <sslim@archi.snu.ac.kr>
Function: binarysearch performs binary search in an array of 15 integer
elements.
This program is completely structured (no unconditional jumps, no exits
from loop bodies), and does not contain switch statements, no do-while
loops.
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bs/bs.c
Original name: bs
Changes: No major functional changes.
License: May be used, modified, and re-distributed freely, but
the SNU-RT Benchmark Suite must be acknowledged
*/
/*
This program is derived from the SNU-RT Benchmark Suite for Worst
Case Timing Analysis by Sung-Soo Lim
*/
/*
Forward declaration of functions
*/
void binarysearch_initSeed( void );
long binarysearch_randomInteger( void );
void binarysearch_init( void );
int binarysearch_return( void );
int binarysearch_binary_search( int );
void binarysearch_main( void );
int main( void );
/*
Declaration of global variables
*/
volatile int binarysearch_seed;
struct binarysearch_DATA {
int key;
int value;
};
struct binarysearch_DATA binarysearch_data[ 15 ];
int binarysearch_result;
/*
Initialization- and return-value-related functions
*/
/*
binarysearch_initSeed initializes the seed used in the "random" number
generator.
*/
void binarysearch_initSeed( void )
{
binarysearch_seed = 0;
}
/*
binarysearch_RandomInteger generates "random" integers between 0 and 8094.
*/
long binarysearch_randomInteger( void )
{
binarysearch_seed = ( ( binarysearch_seed * 133 ) + 81 ) % 8095;
return ( binarysearch_seed );
}
void binarysearch_init( void )
{
int i;
binarysearch_initSeed();
_Pragma( "loopbound min 15 max 15" )
for ( i = 0; i < 15; ++i ) {
binarysearch_data[ i ].key = binarysearch_randomInteger();
binarysearch_data[ i ].value = binarysearch_randomInteger();
}
}
int binarysearch_return( void )
{
return ( binarysearch_result );
}
/*
Algorithm core functions
*/
int binarysearch_binary_search( int x )
{
int fvalue, mid, up, low;
low = 0;
up = 14;
fvalue = -1;
_Pragma( "loopbound min 1 max 4" )
while ( low <= up ) {
mid = ( low + up ) >> 1;
if ( binarysearch_data[ mid ].key == x ) {
/* Item found */
up = low - 1;
fvalue = binarysearch_data[ mid ].value;
} else
if ( binarysearch_data[ mid ].key > x )
/* Item not found */
up = mid - 1;
else
low = mid + 1;
}
return ( fvalue );
}
/*
Main functions
*/
void _Pragma( "entrypoint" ) binarysearch_main( void )
{
binarysearch_result = binarysearch_binary_search( 8 );
}
int main( void )
{
binarysearch_init();
binarysearch_main();
return ( binarysearch_return() - ( -1 ) != 0 );
}

View File

@ -0,0 +1,132 @@
(module $binarysearch.wasm
(type (;0;) (func (param i32 i32)))
(type (;1;) (func))
(type (;2;) (func (result i32)))
(import "__pragma" "loopbound" (func $__pragma_loopbound (type 0)))
(func $__wasm_apply_data_relocs (type 1))
(func $binarysearch_main (type 1)
(local i32 i32 i32 i32 i32)
i32.const 1
i32.const 4
call $__pragma_loopbound
i32.const 14
local.set 0
i32.const 0
local.set 1
block ;; label = @1
loop ;; label = @2
block ;; label = @3
local.get 0
local.get 1
i32.add
i32.const 1
i32.shr_s
local.tee 2
i32.const 3
i32.shl
i32.const 1040
i32.add
local.tee 3
i32.load
local.tee 4
i32.const 8
i32.ne
br_if 0 (;@3;)
local.get 3
i32.load offset=4
local.set 3
br 2 (;@1;)
end
i32.const -1
local.set 3
local.get 1
local.get 2
i32.const 1
i32.add
local.get 4
i32.const 8
i32.gt_s
local.tee 4
select
local.tee 1
local.get 2
i32.const -1
i32.add
local.get 0
local.get 4
select
local.tee 0
i32.le_s
br_if 0 (;@2;)
end
end
i32.const 0
local.get 3
i32.store offset=1160)
(func $__original_main (type 2) (result i32)
(local i32 i32)
i32.const 0
i32.const 0
i32.store offset=1024
i32.const 15
i32.const 15
call $__pragma_loopbound
i32.const -120
local.set 0
loop ;; label = @1
i32.const 0
i32.const 0
i32.load offset=1024
i32.const 133
i32.mul
i32.const 81
i32.add
i32.const 8095
i32.rem_s
i32.store offset=1024
i32.const 0
i32.load offset=1024
local.set 1
i32.const 0
i32.const 0
i32.load offset=1024
i32.const 133
i32.mul
i32.const 81
i32.add
i32.const 8095
i32.rem_s
i32.store offset=1024
local.get 0
i32.const 1160
i32.add
local.get 1
i32.store
local.get 0
i32.const 1164
i32.add
i32.const 0
i32.load offset=1024
i32.store
local.get 0
i32.const 8
i32.add
local.tee 0
br_if 0 (;@1;)
end
call $binarysearch_main
i32.const 0
i32.load offset=1160
i32.const -1
i32.ne)
(table (;0;) 1 1 funcref)
(memory (;0;) 1)
(global $__stack_pointer (mut i32) (i32.const 5264))
(global (;1;) i32 (i32.const 1164))
(global (;2;) i32 (i32.const 5264))
(export "memory" (memory 0))
(export "__wasm_apply_data_relocs" (func $__wasm_apply_data_relocs))
(export "entrypoint" (func $binarysearch_main))
(export "main" (func $__original_main))
(export "__data_end" (global 1))
(export "__heap_base" (global 2)))

View File

@ -0,0 +1,153 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: binarysearch
Author: Sung-Soo Lim <sslim@archi.snu.ac.kr>
Function: binarysearch performs binary search in an array of 15 integer
elements.
This program is completely structured (no unconditional jumps, no exits
from loop bodies), and does not contain switch statements, no do-while
loops.
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bs/bs.c
Original name: bs
Changes: No major functional changes.
License: May be used, modified, and re-distributed freely, but
the SNU-RT Benchmark Suite must be acknowledged
*/
/*
This program is derived from the SNU-RT Benchmark Suite for Worst
Case Timing Analysis by Sung-Soo Lim
*/
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
void binarysearch_initSeed(void);
long binarysearch_randomInteger(void);
void binarysearch_init(void);
int binarysearch_return(void);
int binarysearch_binary_search(int);
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
binarysearch_main(void);
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
/*
Declaration of global variables
*/
volatile int binarysearch_seed;
struct binarysearch_DATA {
int key;
int value;
};
struct binarysearch_DATA binarysearch_data[15];
int binarysearch_result;
/*
Initialization- and return-value-related functions
*/
/*
binarysearch_initSeed initializes the seed used in the "random" number
generator.
*/
void
binarysearch_initSeed(void) {
binarysearch_seed = 0;
}
/*
binarysearch_RandomInteger generates "random" integers between 0 and 8094.
*/
long
binarysearch_randomInteger(void) {
binarysearch_seed = ((binarysearch_seed * 133) + 81) % 8095;
return (binarysearch_seed);
}
void
binarysearch_init(void) {
int i;
binarysearch_initSeed();
__pragma_loopbound(15, 15);
for (i = 0; i < 15; ++i) {
binarysearch_data[i].key = binarysearch_randomInteger();
binarysearch_data[i].value = binarysearch_randomInteger();
}
}
int
binarysearch_return(void) {
return (binarysearch_result);
}
/*
Algorithm core functions
*/
int
binarysearch_binary_search(int x) {
int fvalue, mid, up, low;
low = 0;
up = 14;
fvalue = -1;
__pragma_loopbound(1, 4);
while (low <= up) {
mid = (low + up) >> 1;
if (binarysearch_data[mid].key == x) {
/* Item found */
up = low - 1;
fvalue = binarysearch_data[mid].value;
} else
if (binarysearch_data[mid].key > x)
/* Item not found */
up = mid - 1;
else
low = mid + 1;
}
return (fvalue);
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
binarysearch_main(void) {
binarysearch_result = binarysearch_binary_search(8);
}
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
binarysearch_init();
binarysearch_main();
return (binarysearch_return() - (-1) != 0);
}

View File

@ -0,0 +1,163 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: binarysearch
Author: Sung-Soo Lim <sslim@archi.snu.ac.kr>
Function: binarysearch performs binary search in an array of 15 integer
elements.
This program is completely structured (no unconditional jumps, no exits
from loop bodies), and does not contain switch statements, no do-while
loops.
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bs/bs.c
Original name: bs
Changes: No major functional changes.
License: May be used, modified, and re-distributed freely, but
the SNU-RT Benchmark Suite must be acknowledged
*/
/*
This program is derived from the SNU-RT Benchmark Suite for Worst
Case Timing Analysis by Sung-Soo Lim
*/
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
__attribute__((always_inline)) static inline void binarysearch_initSeed(void);
__attribute__((always_inline)) static inline long
binarysearch_randomInteger(void);
__attribute__((always_inline)) static inline void binarysearch_init(void);
__attribute__((always_inline)) static inline int binarysearch_return(void);
__attribute__((always_inline)) static inline int
binarysearch_binary_search(int);
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
binarysearch_main(void);
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void);
/*
Declaration of global variables
*/
volatile int binarysearch_seed;
struct binarysearch_DATA {
int key;
int value;
};
struct binarysearch_DATA binarysearch_data[15];
int binarysearch_result;
/*
Initialization- and return-value-related functions
*/
/*
binarysearch_initSeed initializes the seed used in the "random" number
generator.
*/
__attribute__((always_inline)) static inline void
binarysearch_initSeed(void) {
binarysearch_seed = 0;
}
/*
binarysearch_RandomInteger generates "random" integers between 0 and 8094.
*/
__attribute__((always_inline)) static inline long
binarysearch_randomInteger(void) {
binarysearch_seed = ((binarysearch_seed * 133) + 81) % 8095;
return (binarysearch_seed);
}
__attribute__((always_inline)) static inline void
binarysearch_init(void) {
int i;
binarysearch_initSeed();
__pragma_loopbound(15, 15);
for (i = 0; i < 15; ++i) {
binarysearch_data[i].key = binarysearch_randomInteger();
binarysearch_data[i].value = binarysearch_randomInteger();
}
}
__attribute__((always_inline)) static inline int
binarysearch_return(void) {
return (binarysearch_result);
}
/*
Algorithm core functions
*/
__attribute__((always_inline)) static inline int
binarysearch_binary_search(int x) {
int fvalue, mid, up, low;
low = 0;
up = 14;
fvalue = -1;
__pragma_loopbound(1, 4);
while (low <= up) {
mid = (low + up) >> 1;
if (binarysearch_data[mid].key == x) {
/* Item found */
up = low - 1;
fvalue = binarysearch_data[mid].value;
} else
if (binarysearch_data[mid].key > x)
/* Item not found */
up = mid - 1;
else
low = mid + 1;
}
return (fvalue);
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
binarysearch_main(void) {
binarysearch_result = binarysearch_binary_search(8);
}
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
binarysearch_init();
binarysearch_main();
return (binarysearch_return() - (-1) != 0);
}

View File

@ -0,0 +1,29 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(bitcount)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/bitcount.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/bitcount.c"
"generated/modified_sources/default/bitcnt_1.c"
"generated/modified_sources/default/bitcnt_2.c"
"generated/modified_sources/default/bitcnt_3.c"
"generated/modified_sources/default/bitcnt_4.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,81 @@
File: bitcnt_1.c
Original provenience:
2017-04-18:
- Annotated bitcount_main as entry-point for timing analysis
2015-10-12:
- Remove comment on line 1
- Added generic TACLeBench header to line 1
- Changed function bit_count to bitcount_bit_count
- Applied Code Style
File: bitcnt_2.c
Original provenience:
2015-10-12:
- Remove comment on line 1
- Added generic TACLeBench header to line 1
- Changed function bitcount to bitcount_bitcount
- Applied Code Style
File: bitcnt_3.c
Original provenience:
2015-10-12:
- Remove comment on line 1
- Added generic TACLeBench header to line 1
- Changed function {name} to bitcount_{name}
- Changed global variable bits to bitcount_bits
- Made int i volatile to prevent compiler optimalizations
- Added the bitcount_init3() function to initialize bitcount_bits during the init fase
- Applied Code Style
File: bitcnt_4.c
Original provenience:
2015-10-12:
- Remove comment on line 1
- Added generic TACLeBench header to line 1
- Changed function {name} to bitcount_{name}
- Changed global variable bits to bitcount_bits
- Made int i volatile to prevent compiler optimalizations
- Added the bitcount_init4() function to initialize bitcount_bits during the init fase
- Applied Code Style
File: bitcount.c
Original provenience:
2015-10-12:
- Remove comment on line 1
- Added generic TACLeBench header to line 1
- Changed global variable _randseed to bitcount_randseed
- Changed function {name} to bitcount_{name}
- Changed external functions to new name
- Moved local variables of main to global variables
- Added bitcount_init function to initialize global variables
- Added bitcount_main function for the calculations
- Added bitcount_main function for the return value
- Applied Code Style
File: bitops.h
Original provenience:
2015-10-12:
- Remove comment on line 1
- Added generic TACLeBench header to line 1
- Removed unused defines
- Removed typedef unsigned int size_t ==> no references
- Replaced CHAR_BIT with value 8 and removed the define
- Applied Code Style
File: sniptype.h
Original provenience:
2015-10-12:
- Removed file, no usage of the definations and typedefs

View File

@ -0,0 +1,3 @@
From http://www.snippets.org/.
This code is FREE with no restrictions.

View File

@ -0,0 +1,36 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_1.c
Author: Ratko Tomic
Function: Test program for bit counting functions
Source: http://www.snippets.org/.
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
int bitcount_bit_count( long x )
{
int n = 0;
/*
** The loop will execute once for each bit of x set, this is in average
** twice as fast as the shift/test method.
*/
if ( x ) {
_Pragma( "loopbound min 3 max 8" )
do {
n++;
} while ( 0 != ( x = x & ( x - 1 ) ) ) ;
}
return ( n );
}

View File

@ -0,0 +1,31 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_2.c
Author: Bob Stout & Auke Reitsma
Function: Test program for bit counting functions
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
int bitcount_bitcount( long i )
{
i = ( ( i & 0xAAAAAAAAL ) >> 1 ) + ( i & 0x55555555L );
i = ( ( i & 0xCCCCCCCCL ) >> 2 ) + ( i & 0x33333333L );
i = ( ( i & 0xF0F0F0F0L ) >> 4 ) + ( i & 0x0F0F0F0FL );
i = ( ( i & 0xFF00FF00L ) >> 8 ) + ( i & 0x00FF00FFL );
i = ( ( i & 0xFFFF0000L ) >> 16 ) + ( i & 0x0000FFFFL );
return ( int )i;
}

View File

@ -0,0 +1,106 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_3.c
Author: Bob Stout & Auke Reitsma
Function: Bit counting functions using table lookup
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
static char bitcount_bits[ 256 ];
/*
** Count bits in each nybble
**
** Note: Only the first 16 table entries are used, the rest could be
** omitted.
*/
void bitcount_init3( void )
{
int volatile i = 0;
char bitcount_bits_tmp[ 256 ] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
for ( i = 0; i < 256; i++ )
bitcount_bits[ i ] = bitcount_bits_tmp[ i ];
}
int bitcount_ntbl_bitcount( long int x )
{
return
bitcount_bits[ ( int ) ( x & 0x0000000FUL ) ] +
bitcount_bits[ ( int )( ( x & 0x000000F0UL ) >> 4 ) ] +
bitcount_bits[ ( int )( ( x & 0x00000F00UL ) >> 8 ) ] +
bitcount_bits[ ( int )( ( x & 0x0000F000UL ) >> 12 ) ] +
bitcount_bits[ ( int )( ( x & 0x000F0000UL ) >> 16 ) ] +
bitcount_bits[ ( int )( ( x & 0x00F00000UL ) >> 20 ) ] +
bitcount_bits[ ( int )( ( x & 0x0F000000UL ) >> 24 ) ] +
bitcount_bits[ ( int )( ( x & 0xF0000000UL ) >> 28 ) ];
}
/*
** Count bits in each byte
**
** by Bruce Wedding, works best on Watcom & Borland
*/
int bitcount_BW_btbl_bitcount( long int x )
{
union {
unsigned char ch[ 4 ];
long y;
} U;
U.y = x;
return bitcount_bits[ U.ch[ 0 ] ] + bitcount_bits[ U.ch[ 1 ] ] +
bitcount_bits[ U.ch[ 3 ] ] + bitcount_bits[ U.ch[ 2 ] ];
}
/*
** Count bits in each byte
**
** by Auke Reitsma, works best on Microsoft, Symantec, and others
*/
int bitcount_AR_btbl_bitcount( long int x )
{
unsigned char *ptr = ( unsigned char * ) & x ;
int accu ;
accu = bitcount_bits[ *ptr++ ];
accu += bitcount_bits[ *ptr++ ];
accu += bitcount_bits[ *ptr++ ];
accu += bitcount_bits[ *ptr ];
return accu;
}

View File

@ -0,0 +1,86 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_4.c
Author: Bob Stout
Function: Recursive bit counting functions using table lookup
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h" /* from Snippets */
static char bitcount_bits[ 256 ];
/*
** Count bits in each nybble
**
** Note: Only the first 16 table entries are used, the rest could be
** omitted.
*/
void bitcount_init4( void )
{
int volatile i = 0;
char bitcount_bits_tmp[ 256 ] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
};
for ( i = 0; i < 256; i++ )
bitcount_bits[ i ] = bitcount_bits_tmp[ i ];
}
int bitcount_ntbl_bitcnt( unsigned long x )
{
int cnt = bitcount_bits[ ( int )( x & 0x0000000FL ) ];
if ( 0L != ( x >>= 4 ) )
cnt += bitcount_ntbl_bitcnt( x );
return cnt;
}
/*
** Count bits in each byte
*/
int bitcount_btbl_bitcnt( unsigned long x )
{
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
int idx = sizeof(x) - 1;
#else
int idx = 0;
#endif
int cnt = bitcount_bits[( ( char * ) & x )[idx] & 0xFF];
if ( 0L != ( x >>= 8 ) )
cnt += bitcount_btbl_bitcnt( x );
return cnt;
}

View File

@ -0,0 +1,146 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcount.c
Author: Bob Stout & Auke Reitsma
Function: test program for bit counting functions
Source: www.snippest.com
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
#define FUNCS 8
/*
Global variables
*/
unsigned long bitcount_randseed;
int bitcount_res;
unsigned long bitcount_seed;
unsigned long bitcount_n;
unsigned int bitcount_iterations;
/*
First declaration of the functions
*/
int bitcount_bit_shifter( long int x );
unsigned long bitcount_random( void );
void bitcount_main();
int bitcount_return();
void bitcount_init();
int main( void );
int bitcount_bit_shifter( long int x )
{
int n;
unsigned int i;
_Pragma( "loopbound min 31 max 31" )
for ( i = n = 0; x && ( i < ( sizeof( long ) * 8 ) ); ++i, x >>= 1 )
n += ( int )( x & 1L );
return n;
}
int bitcount_return()
{
return ( bitcount_n + ( -1095 ) ) != 0;
}
void bitcount_init()
{
bitcount_randseed = 1;
bitcount_n = 0;
bitcount_iterations = 10;
bitcount_init3();
bitcount_init4();
}
unsigned long bitcount_random( void )
{
long x, hi, lo, t;
/*
Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
From "Random number generators: good ones are hard to find",
Park and Miller, Communications of the ACM, vol. 31, no. 10,
October 1988, p. 1195.
*/
x = bitcount_randseed;
hi = x / 127773;
lo = x % 127773;
t = 16807 * lo - 2836 * hi;
if ( t <= 0 )
t += 0x7fffffff;
bitcount_randseed = t;
return ( t );
}
void _Pragma( "entrypoint" ) bitcount_main()
{
unsigned int i, j;
_Pragma( "loopbound min 8 max 8" )
for ( i = 0; i < FUNCS; i++ ) {
_Pragma( "loopbound min 10 max 10" )
for ( j = 0, bitcount_seed = bitcount_random(); j < bitcount_iterations;
j++, bitcount_seed += 13 ) {
// The original calls were done by function pointers
switch ( i ) {
case 0:
bitcount_res = bitcount_bit_count( bitcount_seed );
break;
case 1:
bitcount_res = bitcount_bitcount( bitcount_seed );
break;
case 2: {
_Pragma( "marker call_ntbl" )
bitcount_res = bitcount_ntbl_bitcnt( bitcount_seed );
break;
}
case 3: {
_Pragma( "marker call_btbl" )
bitcount_res = bitcount_btbl_bitcnt( bitcount_seed );
break;
}
case 4:
bitcount_res = bitcount_ntbl_bitcount( bitcount_seed );
break;
case 5:
bitcount_res = bitcount_BW_btbl_bitcount( bitcount_seed );
break;
case 6:
bitcount_res = bitcount_AR_btbl_bitcount( bitcount_seed );
break;
case 7:
bitcount_res = bitcount_bit_shifter( bitcount_seed );
break;
default:
break;
}
bitcount_n += bitcount_res;
}
}
_Pragma( "flowrestriction 1*ntbl_bitcount <= 8*call_ntbl" )
_Pragma( "flowrestriction 1*btbl_bitcount <= 4*call_btbl" )
}
int main( void )
{
bitcount_init();
bitcount_main();
return ( bitcount_return() );
}

View File

@ -0,0 +1,50 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitops.h
Author: Bob Stout & Auke Reitsma
Function: test program for bit counting functions
Source:
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#ifndef BITOPS__H
#define BITOPS__H
/*
** bitcount_1.c
*/
int bitcount_bit_count( long x );
/*
** bitcount_2.c
*/
int bitcount_bitcount( long i );
/*
** bitcount_3.c
*/
void bitcount_init3( void );
int bitcount_ntbl_bitcount( long int x );
int bitcount_BW_btbl_bitcount( long int x );
int bitcount_AR_btbl_bitcount( long int x );
/*
** bitcount_4.c
*/
void bitcount_init4( void );
int bitcount_ntbl_bitcnt( unsigned long x );
int bitcount_btbl_bitcnt( unsigned long x );
#endif /* BITOPS__H */

View File

@ -0,0 +1,584 @@
(module $bitcount.wasm
(type (;0;) (func (param i32 i32)))
(type (;1;) (func))
(type (;2;) (func (result i32)))
(type (;3;) (func (param i32) (result i32)))
(import "__pragma" "loopbound" (func $__pragma_loopbound (type 0)))
(func $__wasm_apply_data_relocs (type 1))
(func $bitcount_main (type 1)
(local i32 i32 i32 i32 i32 i32)
i32.const 8
i32.const 8
call $__pragma_loopbound
i32.const 0
local.set 0
loop ;; label = @1
i32.const 10
i32.const 10
call $__pragma_loopbound
i32.const 0
i32.const 0
i32.load offset=1540
local.tee 1
i32.const 127773
i32.div_s
local.tee 2
i32.const -2836
i32.mul
local.get 1
local.get 2
i32.const 127773
i32.mul
i32.sub
i32.const 16807
i32.mul
i32.add
local.tee 1
i32.const 2147483647
i32.add
local.get 1
local.get 1
i32.const 1
i32.lt_s
select
local.tee 1
i32.store offset=1548
i32.const 0
local.get 1
i32.store offset=1540
block ;; label = @2
i32.const 0
i32.load offset=1544
i32.eqz
br_if 0 (;@2;)
i32.const 0
local.set 3
loop ;; label = @3
block ;; label = @4
block ;; label = @5
block ;; label = @6
block ;; label = @7
block ;; label = @8
block ;; label = @9
block ;; label = @10
block ;; label = @11
block ;; label = @12
local.get 0
br_table 0 (;@12;) 1 (;@11;) 2 (;@10;) 3 (;@9;) 4 (;@8;) 5 (;@7;) 6 (;@6;) 7 (;@5;) 0 (;@12;)
end
local.get 1
call $bitcount_bit_count
local.set 2
br 7 (;@4;)
end
local.get 1
call $bitcount_bitcount
local.set 2
br 6 (;@4;)
end
local.get 1
call $bitcount_ntbl_bitcnt
local.set 2
br 5 (;@4;)
end
local.get 1
call $bitcount_btbl_bitcnt
local.set 2
br 4 (;@4;)
end
local.get 1
call $bitcount_ntbl_bitcount
local.set 2
br 3 (;@4;)
end
local.get 1
call $bitcount_BW_btbl_bitcount
local.set 2
br 2 (;@4;)
end
local.get 1
call $bitcount_AR_btbl_bitcount
local.set 2
br 1 (;@4;)
end
i32.const 31
i32.const 31
call $__pragma_loopbound
block ;; label = @5
local.get 1
br_if 0 (;@5;)
i32.const 0
local.set 2
br 1 (;@4;)
end
i32.const 0
local.set 4
i32.const 0
local.set 2
loop ;; label = @5
local.get 1
i32.const 1
i32.and
local.get 2
i32.add
local.set 2
local.get 1
i32.const 2
i32.lt_u
br_if 1 (;@4;)
local.get 1
i32.const 1
i32.shr_s
local.set 1
local.get 4
i32.const 31
i32.lt_u
local.set 5
local.get 4
i32.const 1
i32.add
local.set 4
local.get 5
br_if 0 (;@5;)
end
end
i32.const 0
local.get 2
i32.store offset=1552
i32.const 0
i32.const 0
i32.load offset=1536
local.get 2
i32.add
i32.store offset=1536
i32.const 0
i32.const 0
i32.load offset=1548
i32.const 13
i32.add
local.tee 1
i32.store offset=1548
local.get 3
i32.const 1
i32.add
local.tee 3
i32.const 0
i32.load offset=1544
i32.lt_u
br_if 0 (;@3;)
end
end
local.get 0
i32.const 1
i32.add
local.tee 0
i32.const 8
i32.ne
br_if 0 (;@1;)
end)
(func $__original_main (type 2) (result i32)
i32.const 0
i32.const 1
i32.store offset=1540
i32.const 0
i32.const 10
i32.store offset=1544
i32.const 0
i32.const 0
i32.store offset=1536
call $bitcount_init3
call $bitcount_init4
call $bitcount_main
i32.const 0
i32.load offset=1536
i32.const 1095
i32.ne)
(func $bitcount_bit_count (type 3) (param i32) (result i32)
(local i32)
block ;; label = @1
local.get 0
br_if 0 (;@1;)
i32.const 0
return
end
i32.const 3
i32.const 8
call $__pragma_loopbound
i32.const 0
local.set 1
loop ;; label = @1
local.get 1
i32.const 1
i32.add
local.set 1
local.get 0
i32.const -1
i32.add
local.get 0
i32.and
local.tee 0
br_if 0 (;@1;)
end
local.get 1)
(func $bitcount_bitcount (type 3) (param i32) (result i32)
local.get 0
i32.const 1
i32.shr_u
i32.const 1431655765
i32.and
local.get 0
i32.const 1431655765
i32.and
i32.add
local.tee 0
i32.const 2
i32.shr_u
i32.const 858993459
i32.and
local.get 0
i32.const 858993459
i32.and
i32.add
local.tee 0
i32.const 4
i32.shr_u
i32.const 117901063
i32.and
local.get 0
i32.const 117901063
i32.and
i32.add
local.tee 0
i32.const 8
i32.shr_u
i32.const 983055
i32.and
local.get 0
i32.const 983055
i32.and
i32.add
local.tee 0
i32.const 16
i32.shr_u
local.get 0
i32.const 31
i32.and
i32.add)
(func $bitcount_init3 (type 1)
(local i32 i32)
global.get $__stack_pointer
i32.const 16
i32.sub
local.tee 0
i32.const 0
i32.store offset=12
local.get 0
i32.const 0
i32.store offset=12
block ;; label = @1
local.get 0
i32.load offset=12
i32.const 255
i32.gt_s
br_if 0 (;@1;)
loop ;; label = @2
local.get 0
i32.load offset=12
local.set 1
local.get 0
i32.load offset=12
i32.const 1568
i32.add
local.get 1
i32.const 1024
i32.add
i32.load8_u
i32.store8
local.get 0
local.get 0
i32.load offset=12
i32.const 1
i32.add
i32.store offset=12
local.get 0
i32.load offset=12
i32.const 256
i32.lt_s
br_if 0 (;@2;)
end
end)
(func $bitcount_ntbl_bitcount (type 3) (param i32) (result i32)
local.get 0
i32.const 4
i32.shr_u
i32.const 15
i32.and
i32.const 1568
i32.add
i32.load8_s
local.get 0
i32.const 15
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 8
i32.shr_u
i32.const 15
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 12
i32.shr_u
i32.const 15
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 16
i32.shr_u
i32.const 15
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 20
i32.shr_u
i32.const 15
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 24
i32.shr_u
i32.const 15
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 28
i32.shr_u
i32.const 1568
i32.add
i32.load8_s
i32.add)
(func $bitcount_BW_btbl_bitcount (type 3) (param i32) (result i32)
local.get 0
i32.const 8
i32.shr_u
i32.const 255
i32.and
i32.const 1568
i32.add
i32.load8_s
local.get 0
i32.const 255
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 24
i32.shr_u
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 16
i32.shr_u
i32.const 255
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add)
(func $bitcount_AR_btbl_bitcount (type 3) (param i32) (result i32)
local.get 0
i32.const 8
i32.shr_u
i32.const 255
i32.and
i32.const 1568
i32.add
i32.load8_s
local.get 0
i32.const 255
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 16
i32.shr_u
i32.const 255
i32.and
i32.const 1568
i32.add
i32.load8_s
i32.add
local.get 0
i32.const 24
i32.shr_u
i32.const 1568
i32.add
i32.load8_s
i32.add)
(func $bitcount_init4 (type 1)
(local i32 i32)
global.get $__stack_pointer
i32.const 16
i32.sub
local.tee 0
i32.const 0
i32.store offset=12
local.get 0
i32.const 0
i32.store offset=12
block ;; label = @1
local.get 0
i32.load offset=12
i32.const 255
i32.gt_s
br_if 0 (;@1;)
loop ;; label = @2
local.get 0
i32.load offset=12
local.set 1
local.get 0
i32.load offset=12
i32.const 1824
i32.add
local.get 1
i32.const 1280
i32.add
i32.load8_u
i32.store8
local.get 0
local.get 0
i32.load offset=12
i32.const 1
i32.add
i32.store offset=12
local.get 0
i32.load offset=12
i32.const 256
i32.lt_s
br_if 0 (;@2;)
end
end)
(func $bitcount_ntbl_bitcnt (type 3) (param i32) (result i32)
(local i32 i32 i32)
local.get 0
i32.const 15
i32.and
i32.const 1824
i32.add
i32.load8_s
local.set 1
i32.const 0
local.set 2
block ;; label = @1
local.get 0
i32.const 16
i32.lt_u
br_if 0 (;@1;)
i32.const 0
local.set 2
loop ;; label = @2
local.get 1
local.get 2
i32.add
local.set 2
local.get 0
i32.const 255
i32.gt_u
local.set 3
local.get 0
i32.const 4
i32.shr_u
local.tee 0
i32.const 15
i32.and
i32.const 1824
i32.add
i32.load8_s
local.set 1
local.get 3
br_if 0 (;@2;)
end
end
local.get 1
local.get 2
i32.add)
(func $bitcount_btbl_bitcnt (type 3) (param i32) (result i32)
(local i32 i32 i32)
local.get 0
i32.const 255
i32.and
i32.const 1824
i32.add
i32.load8_s
local.set 1
i32.const 0
local.set 2
block ;; label = @1
local.get 0
i32.const 256
i32.lt_u
br_if 0 (;@1;)
i32.const 0
local.set 2
loop ;; label = @2
local.get 1
local.get 2
i32.add
local.set 2
local.get 0
i32.const 65535
i32.gt_u
local.set 3
local.get 0
i32.const 8
i32.shr_u
local.tee 0
i32.const 255
i32.and
i32.const 1824
i32.add
i32.load8_s
local.set 1
local.get 3
br_if 0 (;@2;)
end
end
local.get 1
local.get 2
i32.add)
(table (;0;) 1 1 funcref)
(memory (;0;) 1)
(global $__stack_pointer (mut i32) (i32.const 6176))
(global (;1;) i32 (i32.const 2080))
(global (;2;) i32 (i32.const 6176))
(export "memory" (memory 0))
(export "__wasm_apply_data_relocs" (func $__wasm_apply_data_relocs))
(export "entrypoint" (func $bitcount_main))
(export "main" (func $__original_main))
(export "__data_end" (global 1))
(export "__heap_base" (global 2))
(data $.rodata (i32.const 1024) "\00\01\01\02\01\02\02\03\01\02\02\03\02\03\03\04\01\02\02\03\02\03\03\04\02\03\03\04\03\04\04\05\01\02\02\03\02\03\03\04\02\03\03\04\03\04\04\05\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\01\02\02\03\02\03\03\04\02\03\03\04\03\04\04\05\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\03\04\04\05\04\05\05\06\04\05\05\06\05\06\06\07\01\02\02\03\02\03\03\04\02\03\03\04\03\04\04\05\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\03\04\04\05\04\05\05\06\04\05\05\06\05\06\06\07\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\03\04\04\05\04\05\05\06\04\05\05\06\05\06\06\07\03\04\04\05\04\05\05\06\04\05\05\06\05\06\06\07\04\05\05\06\05\06\06\07\05\06\06\07\06\07\07\08\00\01\01\02\01\02\02\03\01\02\02\03\02\03\03\04\01\02\02\03\02\03\03\04\02\03\03\04\03\04\04\05\01\02\02\03\02\03\03\04\02\03\03\04\03\04\04\05\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\01\02\02\03\02\03\03\04\02\03\03\04\03\04\04\05\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\03\04\04\05\04\05\05\06\04\05\05\06\05\06\06\07\01\02\02\03\02\03\03\04\02\03\03\04\03\04\04\05\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\03\04\04\05\04\05\05\06\04\05\05\06\05\06\06\07\02\03\03\04\03\04\04\05\03\04\04\05\04\05\05\06\03\04\04\05\04\05\05\06\04\05\05\06\05\06\06\07\03\04\04\05\04\05\05\06\04\05\05\06\05\06\06\07\04\05\05\06\05\06\06\07\05\06\06\07\06\07\07\08"))

View File

@ -0,0 +1,41 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_1.c
Author: Ratko Tomic
Function: Test program for bit counting functions
Source: http://www.snippets.org/.
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
int
bitcount_bit_count(long x) {
int n = 0;
/*
** The loop will execute once for each bit of x set, this is in average
** twice as fast as the shift/test method.
*/
if (x) {
__pragma_loopbound(3, 8);
do {
n++;
} while (0 != (x = x & (x - 1)));
}
return (n);
}

View File

@ -0,0 +1,30 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_2.c
Author: Bob Stout & Auke Reitsma
Function: Test program for bit counting functions
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
int
bitcount_bitcount(long i) {
i = ((i & 0xAAAAAAAAL) >> 1) + (i & 0x55555555L);
i = ((i & 0xCCCCCCCCL) >> 2) + (i & 0x33333333L);
i = ((i & 0xF0F0F0F0L) >> 4) + (i & 0x0F0F0F0FL);
i = ((i & 0xFF00FF00L) >> 8) + (i & 0x00FF00FFL);
i = ((i & 0xFFFF0000L) >> 16) + (i & 0x0000FFFFL);
return (int) i;
}

View File

@ -0,0 +1,98 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_3.c
Author: Bob Stout & Auke Reitsma
Function: Bit counting functions using table lookup
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
static char bitcount_bits[256];
/*
** Count bits in each nybble
**
** Note: Only the first 16 table entries are used, the rest could be
** omitted.
*/
void
bitcount_init3(void) {
int volatile i = 0;
char bitcount_bits_tmp[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
for (i = 0; i < 256; i++)
bitcount_bits[i] = bitcount_bits_tmp[i];
}
int
bitcount_ntbl_bitcount(long int x) {
return bitcount_bits[(int) (x & 0x0000000FUL)] +
bitcount_bits[(int) ((x & 0x000000F0UL) >> 4)] +
bitcount_bits[(int) ((x & 0x00000F00UL) >> 8)] +
bitcount_bits[(int) ((x & 0x0000F000UL) >> 12)] +
bitcount_bits[(int) ((x & 0x000F0000UL) >> 16)] +
bitcount_bits[(int) ((x & 0x00F00000UL) >> 20)] +
bitcount_bits[(int) ((x & 0x0F000000UL) >> 24)] +
bitcount_bits[(int) ((x & 0xF0000000UL) >> 28)];
}
/*
** Count bits in each byte
**
** by Bruce Wedding, works best on Watcom & Borland
*/
int
bitcount_BW_btbl_bitcount(long int x) {
union {
unsigned char ch[4];
long y;
} U;
U.y = x;
return bitcount_bits[U.ch[0]] + bitcount_bits[U.ch[1]] +
bitcount_bits[U.ch[3]] + bitcount_bits[U.ch[2]];
}
/*
** Count bits in each byte
**
** by Auke Reitsma, works best on Microsoft, Symantec, and others
*/
int
bitcount_AR_btbl_bitcount(long int x) {
unsigned char *ptr = (unsigned char *) &x;
int accu;
accu = bitcount_bits[*ptr++];
accu += bitcount_bits[*ptr++];
accu += bitcount_bits[*ptr++];
accu += bitcount_bits[*ptr];
return accu;
}

View File

@ -0,0 +1,79 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_4.c
Author: Bob Stout
Function: Recursive bit counting functions using table lookup
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h" /* from Snippets */
static char bitcount_bits[256];
/*
** Count bits in each nybble
**
** Note: Only the first 16 table entries are used, the rest could be
** omitted.
*/
void
bitcount_init4(void) {
int volatile i = 0;
char bitcount_bits_tmp[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
for (i = 0; i < 256; i++)
bitcount_bits[i] = bitcount_bits_tmp[i];
}
int
bitcount_ntbl_bitcnt(unsigned long x) {
int cnt = bitcount_bits[(int) (x & 0x0000000FL)];
if (0L != (x >>= 4))
cnt += bitcount_ntbl_bitcnt(x);
return cnt;
}
/*
** Count bits in each byte
*/
int
bitcount_btbl_bitcnt(unsigned long x) {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
int idx = sizeof(x) - 1;
#else
int idx = 0;
#endif
int cnt = bitcount_bits[((char *) &x)[idx] & 0xFF];
if (0L != (x >>= 8))
cnt += bitcount_btbl_bitcnt(x);
return cnt;
}

View File

@ -0,0 +1,150 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcount.c
Author: Bob Stout & Auke Reitsma
Function: test program for bit counting functions
Source: www.snippest.com
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
#define FUNCS 8
/*
Global variables
*/
unsigned long bitcount_randseed;
int bitcount_res;
unsigned long bitcount_seed;
unsigned long bitcount_n;
unsigned int bitcount_iterations;
/*
First declaration of the functions
*/
int bitcount_bit_shifter(long int x);
unsigned long bitcount_random(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bitcount_main();
int bitcount_return();
void bitcount_init();
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
int
bitcount_bit_shifter(long int x) {
int n;
unsigned int i;
__pragma_loopbound(31, 31);
for (i = n = 0; x && (i < (sizeof(long) * 8)); ++i, x >>= 1)
n += (int) (x & 1L);
return n;
}
int
bitcount_return() {
return (bitcount_n + (-1095)) != 0;
}
void
bitcount_init() {
bitcount_randseed = 1;
bitcount_n = 0;
bitcount_iterations = 10;
bitcount_init3();
bitcount_init4();
}
unsigned long
bitcount_random(void) {
long x, hi, lo, t;
/*
Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
From "Random number generators: good ones are hard to find",
Park and Miller, Communications of the ACM, vol. 31, no. 10,
October 1988, p. 1195.
*/
x = bitcount_randseed;
hi = x / 127773;
lo = x % 127773;
t = 16807 * lo - 2836 * hi;
if (t <= 0)
t += 0x7fffffff;
bitcount_randseed = t;
return (t);
}
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bitcount_main() {
unsigned int i, j;
__pragma_loopbound(8, 8);
for (i = 0; i < FUNCS; i++) {
__pragma_loopbound(10, 10);
for (j = 0, bitcount_seed = bitcount_random(); j < bitcount_iterations;
j++, bitcount_seed += 13) {
// The original calls were done by function pointers
switch (i) {
case 0:
bitcount_res = bitcount_bit_count(bitcount_seed);
break;
case 1:
bitcount_res = bitcount_bitcount(bitcount_seed);
break;
case 2: {
_Pragma("marker call_ntbl") bitcount_res =
bitcount_ntbl_bitcnt(bitcount_seed);
break;
}
case 3: {
_Pragma("marker call_btbl") bitcount_res =
bitcount_btbl_bitcnt(bitcount_seed);
break;
}
case 4:
bitcount_res = bitcount_ntbl_bitcount(bitcount_seed);
break;
case 5:
bitcount_res = bitcount_BW_btbl_bitcount(bitcount_seed);
break;
case 6:
bitcount_res = bitcount_AR_btbl_bitcount(bitcount_seed);
break;
case 7:
bitcount_res = bitcount_bit_shifter(bitcount_seed);
break;
default:
break;
}
bitcount_n += bitcount_res;
}
}
_Pragma("flowrestriction 1*ntbl_bitcount <= 8*call_ntbl")
_Pragma("flowrestriction 1*btbl_bitcount <= 4*call_btbl")
}
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
bitcount_init();
bitcount_main();
return (bitcount_return());
}

View File

@ -0,0 +1,50 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitops.h
Author: Bob Stout & Auke Reitsma
Function: test program for bit counting functions
Source:
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#ifndef BITOPS__H
#define BITOPS__H
/*
** bitcount_1.c
*/
int bitcount_bit_count(long x);
/*
** bitcount_2.c
*/
int bitcount_bitcount(long i);
/*
** bitcount_3.c
*/
void bitcount_init3(void);
int bitcount_ntbl_bitcount(long int x);
int bitcount_BW_btbl_bitcount(long int x);
int bitcount_AR_btbl_bitcount(long int x);
/*
** bitcount_4.c
*/
void bitcount_init4(void);
int bitcount_ntbl_bitcnt(unsigned long x);
int bitcount_btbl_bitcnt(unsigned long x);
#endif /* BITOPS__H */

View File

@ -0,0 +1,41 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_1.c
Author: Ratko Tomic
Function: Test program for bit counting functions
Source: http://www.snippets.org/.
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
__attribute__((always_inline)) static inline int
bitcount_bit_count(long x) {
int n = 0;
/*
** The loop will execute once for each bit of x set, this is in average
** twice as fast as the shift/test method.
*/
if (x) {
__pragma_loopbound(3, 8);
do {
n++;
} while (0 != (x = x & (x - 1)));
}
return (n);
}

View File

@ -0,0 +1,30 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_2.c
Author: Bob Stout & Auke Reitsma
Function: Test program for bit counting functions
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
__attribute__((always_inline)) static inline int
bitcount_bitcount(long i) {
i = ((i & 0xAAAAAAAAL) >> 1) + (i & 0x55555555L);
i = ((i & 0xCCCCCCCCL) >> 2) + (i & 0x33333333L);
i = ((i & 0xF0F0F0F0L) >> 4) + (i & 0x0F0F0F0FL);
i = ((i & 0xFF00FF00L) >> 8) + (i & 0x00FF00FFL);
i = ((i & 0xFFFF0000L) >> 16) + (i & 0x0000FFFFL);
return (int) i;
}

View File

@ -0,0 +1,98 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_3.c
Author: Bob Stout & Auke Reitsma
Function: Bit counting functions using table lookup
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
static char bitcount_bits[256];
/*
** Count bits in each nybble
**
** Note: Only the first 16 table entries are used, the rest could be
** omitted.
*/
__attribute__((always_inline)) static inline void
bitcount_init3(void) {
int volatile i = 0;
char bitcount_bits_tmp[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
for (i = 0; i < 256; i++)
bitcount_bits[i] = bitcount_bits_tmp[i];
}
__attribute__((always_inline)) static inline int
bitcount_ntbl_bitcount(long int x) {
return bitcount_bits[(int) (x & 0x0000000FUL)] +
bitcount_bits[(int) ((x & 0x000000F0UL) >> 4)] +
bitcount_bits[(int) ((x & 0x00000F00UL) >> 8)] +
bitcount_bits[(int) ((x & 0x0000F000UL) >> 12)] +
bitcount_bits[(int) ((x & 0x000F0000UL) >> 16)] +
bitcount_bits[(int) ((x & 0x00F00000UL) >> 20)] +
bitcount_bits[(int) ((x & 0x0F000000UL) >> 24)] +
bitcount_bits[(int) ((x & 0xF0000000UL) >> 28)];
}
/*
** Count bits in each byte
**
** by Bruce Wedding, works best on Watcom & Borland
*/
__attribute__((always_inline)) static inline int
bitcount_BW_btbl_bitcount(long int x) {
union {
unsigned char ch[4];
long y;
} U;
U.y = x;
return bitcount_bits[U.ch[0]] + bitcount_bits[U.ch[1]] +
bitcount_bits[U.ch[3]] + bitcount_bits[U.ch[2]];
}
/*
** Count bits in each byte
**
** by Auke Reitsma, works best on Microsoft, Symantec, and others
*/
__attribute__((always_inline)) static inline int
bitcount_AR_btbl_bitcount(long int x) {
unsigned char *ptr = (unsigned char *) &x;
int accu;
accu = bitcount_bits[*ptr++];
accu += bitcount_bits[*ptr++];
accu += bitcount_bits[*ptr++];
accu += bitcount_bits[*ptr];
return accu;
}

View File

@ -0,0 +1,79 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcnt_4.c
Author: Bob Stout
Function: Recursive bit counting functions using table lookup
Source: http://www.snippets.org/
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h" /* from Snippets */
static char bitcount_bits[256];
/*
** Count bits in each nybble
**
** Note: Only the first 16 table entries are used, the rest could be
** omitted.
*/
__attribute__((always_inline)) static inline void
bitcount_init4(void) {
int volatile i = 0;
char bitcount_bits_tmp[256] = {
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2, 2, 3, 2, 3, 3, 4,
2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5,
3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6,
4, 5, 5, 6, 5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7,
4, 5, 5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8};
for (i = 0; i < 256; i++)
bitcount_bits[i] = bitcount_bits_tmp[i];
}
__attribute__((always_inline)) static inline int
bitcount_ntbl_bitcnt(unsigned long x) {
int cnt = bitcount_bits[(int) (x & 0x0000000FL)];
if (0L != (x >>= 4))
cnt += bitcount_ntbl_bitcnt(x);
return cnt;
}
/*
** Count bits in each byte
*/
__attribute__((always_inline)) static inline int
bitcount_btbl_bitcnt(unsigned long x) {
#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
int idx = sizeof(x) - 1;
#else
int idx = 0;
#endif
int cnt = bitcount_bits[((char *) &x)[idx] & 0xFF];
if (0L != (x >>= 8))
cnt += bitcount_btbl_bitcnt(x);
return cnt;
}

View File

@ -0,0 +1,164 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitcount.c
Author: Bob Stout & Auke Reitsma
Function: test program for bit counting functions
Source: www.snippest.com
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#include "bitops.h"
// Wasm loop bounds
#include "bitcnt_1.c"
#include "bitcnt_2.c"
#include "bitcnt_3.c"
#include "bitcnt_4.c"
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
#define FUNCS 8
/*
Global variables
*/
unsigned long bitcount_randseed;
int bitcount_res;
unsigned long bitcount_seed;
unsigned long bitcount_n;
unsigned int bitcount_iterations;
/*
First declaration of the functions
*/
__attribute__((always_inline)) static inline int
bitcount_bit_shifter(long int x);
__attribute__((always_inline)) static inline unsigned long
bitcount_random(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bitcount_main();
__attribute__((always_inline)) static inline int bitcount_return();
__attribute__((always_inline)) static inline void bitcount_init();
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void);
__attribute__((always_inline)) static inline int
bitcount_bit_shifter(long int x) {
int n;
unsigned int i;
__pragma_loopbound(31, 31);
for (i = n = 0; x && (i < (sizeof(long) * 8)); ++i, x >>= 1)
n += (int) (x & 1L);
return n;
}
__attribute__((always_inline)) static inline int
bitcount_return() {
return (bitcount_n + (-1095)) != 0;
}
__attribute__((always_inline)) static inline void
bitcount_init() {
bitcount_randseed = 1;
bitcount_n = 0;
bitcount_iterations = 10;
bitcount_init3();
bitcount_init4();
}
__attribute__((always_inline)) static inline unsigned long
bitcount_random(void) {
long x, hi, lo, t;
/*
Compute x[n + 1] = (7^5 * x[n]) mod (2^31 - 1).
From "Random number generators: good ones are hard to find",
Park and Miller, Communications of the ACM, vol. 31, no. 10,
October 1988, p. 1195.
*/
x = bitcount_randseed;
hi = x / 127773;
lo = x % 127773;
t = 16807 * lo - 2836 * hi;
if (t <= 0)
t += 0x7fffffff;
bitcount_randseed = t;
return (t);
}
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bitcount_main() {
unsigned int i, j;
__pragma_loopbound(8, 8);
for (i = 0; i < FUNCS; i++) {
__pragma_loopbound(10, 10);
for (j = 0, bitcount_seed = bitcount_random(); j < bitcount_iterations;
j++, bitcount_seed += 13) {
// The original calls were done by function pointers
switch (i) {
case 0:
bitcount_res = bitcount_bit_count(bitcount_seed);
break;
case 1:
bitcount_res = bitcount_bitcount(bitcount_seed);
break;
case 2: {
_Pragma("marker call_ntbl") bitcount_res =
bitcount_ntbl_bitcnt(bitcount_seed);
break;
}
case 3: {
_Pragma("marker call_btbl") bitcount_res =
bitcount_btbl_bitcnt(bitcount_seed);
break;
}
case 4:
bitcount_res = bitcount_ntbl_bitcount(bitcount_seed);
break;
case 5:
bitcount_res = bitcount_BW_btbl_bitcount(bitcount_seed);
break;
case 6:
bitcount_res = bitcount_AR_btbl_bitcount(bitcount_seed);
break;
case 7:
bitcount_res = bitcount_bit_shifter(bitcount_seed);
break;
default:
break;
}
bitcount_n += bitcount_res;
}
}
_Pragma("flowrestriction 1*ntbl_bitcount <= 8*call_ntbl")
_Pragma("flowrestriction 1*btbl_bitcount <= 4*call_btbl")
}
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
bitcount_init();
bitcount_main();
return (bitcount_return());
}

View File

@ -0,0 +1,55 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.x
Name: bitops.h
Author: Bob Stout & Auke Reitsma
Function: test program for bit counting functions
Source:
Changes: no major functional changes
License: May be used, modified, and re-distributed freely.
*/
#ifndef BITOPS__H
#define BITOPS__H
/*
** bitcount_1.c
*/
__attribute__((always_inline)) static inline int bitcount_bit_count(long x);
/*
** bitcount_2.c
*/
__attribute__((always_inline)) static inline int bitcount_bitcount(long i);
/*
** bitcount_3.c
*/
__attribute__((always_inline)) static inline void bitcount_init3(void);
__attribute__((always_inline)) static inline int
bitcount_ntbl_bitcount(long int x);
__attribute__((always_inline)) static inline int
bitcount_BW_btbl_bitcount(long int x);
__attribute__((always_inline)) static inline int
bitcount_AR_btbl_bitcount(long int x);
/*
** bitcount_4.c
*/
__attribute__((always_inline)) static inline void bitcount_init4(void);
__attribute__((always_inline)) static inline int
bitcount_ntbl_bitcnt(unsigned long x);
__attribute__((always_inline)) static inline int
bitcount_btbl_bitcnt(unsigned long x);
#endif /* BITOPS__H */

View File

@ -0,0 +1,25 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(bitonic)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/bitonic.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/bitonic.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,53 @@
File: bitonic.c
Original provenience: StreamIt benchmark suite,
http://groups.csail.mit.edu/cag/streamit/results/bitonic/code/c/
2015-10-20:
- Removed original header comment, replaced by TACLeBench header.
- Added prefix "bitonic_"/"BITONIC_" to all global symbols
- adjusted names of bitonicSort and bitonicMerge functions to
bitonic_*.
- Replaced initialization code by TACLeBench-compliant initialization code.
- Added new function quicksort_return producing a checksum as return value.
- Added new function quicksort_main according to TACLeBench guidelines.
quicksort_main is annotated as entry-point for timing analysis.
- Applied code formatting according to the following rules
- Lines shall not be wider than 80 characters; whenever possible, appropriate
line breaks shall be inserted to keep lines below 80 characters
- Indentation is done using whitespaces only, no tabs. Code is indented by
two whitespaces
- Two empty lines are put between any two functions
- In non-empty lists or index expressions, opening '(' and '[' are followed by
one whitespace, closing ')' and ']' are preceded by one whitespace
- In comma- or colon-separated argument lists, one whitespace is put after
each comma/colon
- Names of functions and global variables all start with a benchmark-specific
prefix (here: bs_) followed by lowercase letter (e.g., bs_square)
- For pointer types, one whitespace is put before the '*'
- Operators within expressions shall be preceded and followed by one
whitespace
- Code of then- and else-parts of if-then-else statements shall be put in
separate lines, not in the same lines as the if-condition or the keyword
"else"
- Opening braces '{' denoting the beginning of code for some if-else or loop
body shall be put at the end of the same line where the keywords "if",
"else", "for", "while" etc. occur
2016-02-01:
- More formatting:
- In non-empty lists or index expressions, opening '(' and '[' are followed by
one whitespace, closing ')' and ']' are preceded by one whitespace
- Operators within expressions shall be preceded and followed by one
whitespace
2016-04-05:
- Return '0' on success
2016-04-06:
- Fixed generation of return value
2016-06-01:
- Changed all prefixes to lower-case

View File

@ -0,0 +1,157 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: bitonic
Author: Chris Leger
Function: bitonic implements a recursive sorting network algorithm.
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Changes: no major functional changes
License: MIT
*/
/*
Forward declaration of functions
*/
void bitonic_init( void );
int bitonic_return( void );
void bitonic_compare( int i, int j, int dir );
void bitonic_merge( int lo, int cnt, int dir );
void bitonic_sort( int lo, int cnt, int dir );
int main( void );
/*
Declaration of global variables
*/
int bitonic_numiters = 10;
int bitonic_a[ 32 ]; // the array to be sorted
const int bitonic_ASCENDING = 1;
const int bitonic_DESCENDING = 0;
const int bitonic_CHECKSUM = 55;
/*
Initialization- and return-value-related functions
*/
void bitonic_init( void )
{
/** Initialize array "a" with data **/
int i;
_Pragma( "loopbound min 32 max 32" )
for ( i = 0; i < 32; i++ )
bitonic_a[ i ] = ( 32 - i );
}
int bitonic_return( void )
{
int checksum = 0;
checksum += bitonic_a[ 0 ] + bitonic_a[ 21 ] + bitonic_a[ 31 ];
return ( ( checksum == bitonic_CHECKSUM ) ? 0 : -1 );
}
/*
Algorithm core functions
*/
/** A comparator is modelled by the procedure compare, where the
parameter dir indicates the sorting direction. If dir is ASCENDING
and a[i] > a[j] is true or dir is DESCENDING and a[i] > a[j] is
false then a[i] and a[j] are interchanged.
**/
void bitonic_compare( int i, int j, int dir )
{
if ( dir == ( bitonic_a[ i ] > bitonic_a[ j ] ) ) {
int h = bitonic_a[ i ];
bitonic_a[ i ] = bitonic_a[ j ];
bitonic_a[ j ] = h;
}
}
/** The procedure bitonicMerge recursively sorts a bitonic sequence in
ascending order, if dir = ASCENDING, and in descending order
otherwise. The sequence to be sorted starts at index position lo,
the number of elements is cnt.
**/
void bitonic_merge( int lo, int cnt, int dir )
{
int k = cnt / 2;
int i;
_Pragma( "loopbound min 0 max 16" )
for ( i = lo; i < lo + k; i++ )
bitonic_compare( i, i + k, dir );
if ( k > 1 ) {
bitonic_merge( lo, k, dir );
bitonic_merge( lo + k, k, dir );
}
}
/** Procedure bitonicSort first produces a bitonic sequence by
recursively sorting its two halves in opposite directions, and then
calls bitonicMerge.
**/
void bitonic_sort( int lo, int cnt, int dir )
{
int k = cnt;
k /= 2;
_Pragma( "marker recMerge" )
if ( cnt > 1 ) {
bitonic_sort( lo, k, bitonic_ASCENDING );
bitonic_sort( lo + k, k, bitonic_DESCENDING );
}
bitonic_merge( lo, cnt, dir );
_Pragma( "flowrestriction 1*bitonicMerge <= 31*recMerge" )
return;
}
/*
Main functions
*/
void _Pragma ( "entrypoint" ) bitonic_main( void )
{
int i;
/** When called with parameters lo = 0, cnt = a.length() and dir =
ASCENDING, procedure bitonicSort sorts the whole array a. **/
_Pragma( "marker recSort" )
bitonic_sort( 0, 32, bitonic_ASCENDING );
_Pragma( "flowrestriction 1*bitonicSort <= 63*recSort" )
/** Loop through array, printing out each element **/
_Pragma( "loopbound min 32 max 32" )
for ( i = 0; i < 32; i++ ) {
}
}
int main( void )
{
bitonic_init();
bitonic_main();
return ( bitonic_return() );
}

View File

@ -0,0 +1,215 @@
(module $bitonic.wasm
(type (;0;) (func (param i32 i32)))
(type (;1;) (func))
(type (;2;) (func (param i32 i32 i32)))
(type (;3;) (func (result i32)))
(import "__pragma" "loopbound" (func $__pragma_loopbound (type 0)))
(func $__wasm_apply_data_relocs (type 1))
(func $bitonic_merge (type 2) (param i32 i32 i32)
(local i32 i32 i32 i32 i32 i32 i32 i32 i32)
i32.const 0
i32.const 16
call $__pragma_loopbound
block ;; label = @1
local.get 1
i32.const 2
i32.lt_s
br_if 0 (;@1;)
local.get 1
i32.const 1
i32.shr_u
local.tee 3
local.get 0
i32.add
local.set 4
loop ;; label = @2
local.get 4
local.set 5
local.get 0
i32.const 2
i32.shl
local.set 4
local.get 3
local.tee 6
i32.const 2
i32.shl
i32.const 1024
i32.add
local.set 7
local.get 0
local.set 3
loop ;; label = @3
block ;; label = @4
local.get 4
i32.const 1024
i32.add
local.tee 8
i32.load
local.tee 9
local.get 7
local.get 4
i32.add
local.tee 10
i32.load
local.tee 11
i32.gt_s
local.get 2
i32.ne
br_if 0 (;@4;)
local.get 8
local.get 11
i32.store
local.get 10
local.get 9
i32.store
end
local.get 4
i32.const 4
i32.add
local.set 4
local.get 3
i32.const 1
i32.add
local.tee 3
local.get 5
i32.lt_s
br_if 0 (;@3;)
end
local.get 1
i32.const 4
i32.lt_s
br_if 1 (;@1;)
local.get 0
local.get 6
local.get 2
call $bitonic_merge
i32.const 0
i32.const 16
call $__pragma_loopbound
local.get 6
i32.const 2
i32.div_s
local.tee 3
local.get 5
i32.add
local.set 4
local.get 6
local.set 1
local.get 5
local.set 0
local.get 6
i32.const 1
i32.gt_s
br_if 0 (;@2;)
end
end)
(func $bitonic_sort (type 2) (param i32 i32 i32)
(local i32)
block ;; label = @1
local.get 1
i32.const 2
i32.lt_s
br_if 0 (;@1;)
local.get 0
local.get 1
i32.const 1
i32.shr_u
local.tee 3
i32.const 1
call $bitonic_sort
local.get 3
local.get 0
i32.add
local.get 3
i32.const 0
call $bitonic_sort
end
local.get 0
local.get 1
local.get 2
call $bitonic_merge)
(func $bitonic_main (type 1)
i32.const 0
i32.const 32
i32.const 1
call $bitonic_sort
i32.const 32
i32.const 32
call $__pragma_loopbound)
(func $__original_main (type 3) (result i32)
i32.const 32
i32.const 32
call $__pragma_loopbound
i32.const 0
i64.const 4294967298
i64.store offset=1144
i32.const 0
i64.const 12884901892
i64.store offset=1136
i32.const 0
i64.const 21474836486
i64.store offset=1128
i32.const 0
i64.const 30064771080
i64.store offset=1120
i32.const 0
i64.const 38654705674
i64.store offset=1112
i32.const 0
i64.const 47244640268
i64.store offset=1104
i32.const 0
i64.const 55834574862
i64.store offset=1096
i32.const 0
i64.const 64424509456
i64.store offset=1088
i32.const 0
i64.const 73014444050
i64.store offset=1080
i32.const 0
i64.const 81604378644
i64.store offset=1072
i32.const 0
i64.const 90194313238
i64.store offset=1064
i32.const 0
i64.const 98784247832
i64.store offset=1056
i32.const 0
i64.const 107374182426
i64.store offset=1048
i32.const 0
i64.const 115964117020
i64.store offset=1040
i32.const 0
i64.const 124554051614
i64.store offset=1032
i32.const 0
i64.const 133143986208
i64.store offset=1024
call $bitonic_main
i32.const -1
i32.const 0
i32.const 0
i32.load offset=1108
i32.const 0
i32.load offset=1024
i32.add
i32.const 0
i32.load offset=1148
i32.add
i32.const 55
i32.ne
select)
(table (;0;) 1 1 funcref)
(memory (;0;) 1)
(global $__stack_pointer (mut i32) (i32.const 5248))
(global (;1;) i32 (i32.const 1152))
(global (;2;) i32 (i32.const 5248))
(export "memory" (memory 0))
(export "__wasm_apply_data_relocs" (func $__wasm_apply_data_relocs))
(export "entrypoint" (func $bitonic_main))
(export "main" (func $__original_main))
(export "__data_end" (global 1))
(export "__heap_base" (global 2)))

View File

@ -0,0 +1,154 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: bitonic
Author: Chris Leger
Function: bitonic implements a recursive sorting network algorithm.
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Changes: no major functional changes
License: MIT
*/
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
void bitonic_init(void);
int bitonic_return(void);
void bitonic_compare(int i, int j, int dir);
void bitonic_merge(int lo, int cnt, int dir);
void bitonic_sort(int lo, int cnt, int dir);
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
/*
Declaration of global variables
*/
int bitonic_numiters = 10;
int bitonic_a[32]; // the array to be sorted
const int bitonic_ASCENDING = 1;
const int bitonic_DESCENDING = 0;
const int bitonic_CHECKSUM = 55;
/*
Initialization- and return-value-related functions
*/
void
bitonic_init(void) {
/** Initialize array "a" with data **/
int i;
__pragma_loopbound(32, 32);
for (i = 0; i < 32; i++)
bitonic_a[i] = (32 - i);
}
int
bitonic_return(void) {
int checksum = 0;
checksum += bitonic_a[0] + bitonic_a[21] + bitonic_a[31];
return ((checksum == bitonic_CHECKSUM) ? 0 : -1);
}
/*
Algorithm core functions
*/
/** A comparator is modelled by the procedure compare, where the
parameter dir indicates the sorting direction. If dir is ASCENDING
and a[i] > a[j] is true or dir is DESCENDING and a[i] > a[j] is
false then a[i] and a[j] are interchanged.
**/
void
bitonic_compare(int i, int j, int dir) {
if (dir == (bitonic_a[i] > bitonic_a[j])) {
int h = bitonic_a[i];
bitonic_a[i] = bitonic_a[j];
bitonic_a[j] = h;
}
}
/** The procedure bitonicMerge recursively sorts a bitonic sequence in
ascending order, if dir = ASCENDING, and in descending order
otherwise. The sequence to be sorted starts at index position lo,
the number of elements is cnt.
**/
void
bitonic_merge(int lo, int cnt, int dir) {
int k = cnt / 2;
int i;
__pragma_loopbound(0, 16);
for (i = lo; i < lo + k; i++)
bitonic_compare(i, i + k, dir);
if (k > 1) {
bitonic_merge(lo, k, dir);
bitonic_merge(lo + k, k, dir);
}
}
/** Procedure bitonicSort first produces a bitonic sequence by
recursively sorting its two halves in opposite directions, and then
calls bitonicMerge.
**/
void
bitonic_sort(int lo, int cnt, int dir) {
int k = cnt;
k /= 2;
_Pragma("marker recMerge")
if (cnt > 1) {
bitonic_sort(lo, k, bitonic_ASCENDING);
bitonic_sort(lo + k, k, bitonic_DESCENDING);
}
bitonic_merge(lo, cnt, dir);
_Pragma("flowrestriction 1*bitonicMerge <= 31*recMerge")
return;
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bitonic_main(void) {
int i;
/** When called with parameters lo = 0, cnt = a.length() and dir =
ASCENDING, procedure bitonicSort sorts the whole array a. **/
_Pragma("marker recSort") bitonic_sort(0, 32, bitonic_ASCENDING);
_Pragma("flowrestriction 1*bitonicSort <= 63*recSort")
/** Loop through array, printing out each element **/
__pragma_loopbound(32, 32);
for (i = 0; i < 32; i++) {
}
}
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
bitonic_init();
bitonic_main();
return (bitonic_return());
}

View File

@ -0,0 +1,164 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: bitonic
Author: Chris Leger
Function: bitonic implements a recursive sorting network algorithm.
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Changes: no major functional changes
License: MIT
*/
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
__attribute__((always_inline)) static inline void bitonic_init(void);
__attribute__((always_inline)) static inline int bitonic_return(void);
__attribute__((always_inline)) static inline void bitonic_compare(int i, int j,
int dir);
__attribute__((always_inline)) static inline void bitonic_merge(int lo, int cnt,
int dir);
__attribute__((always_inline)) static inline void bitonic_sort(int lo, int cnt,
int dir);
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void);
/*
Declaration of global variables
*/
int bitonic_numiters = 10;
int bitonic_a[32]; // the array to be sorted
const int bitonic_ASCENDING = 1;
const int bitonic_DESCENDING = 0;
const int bitonic_CHECKSUM = 55;
/*
Initialization- and return-value-related functions
*/
__attribute__((always_inline)) static inline void
bitonic_init(void) {
/** Initialize array "a" with data **/
int i;
__pragma_loopbound(32, 32);
for (i = 0; i < 32; i++)
bitonic_a[i] = (32 - i);
}
__attribute__((always_inline)) static inline int
bitonic_return(void) {
int checksum = 0;
checksum += bitonic_a[0] + bitonic_a[21] + bitonic_a[31];
return ((checksum == bitonic_CHECKSUM) ? 0 : -1);
}
/*
Algorithm core functions
*/
/** A comparator is modelled by the procedure compare, where the
parameter dir indicates the sorting direction. If dir is ASCENDING
and a[i] > a[j] is true or dir is DESCENDING and a[i] > a[j] is
false then a[i] and a[j] are interchanged.
**/
__attribute__((always_inline)) static inline void
bitonic_compare(int i, int j, int dir) {
if (dir == (bitonic_a[i] > bitonic_a[j])) {
int h = bitonic_a[i];
bitonic_a[i] = bitonic_a[j];
bitonic_a[j] = h;
}
}
/** The procedure bitonicMerge recursively sorts a bitonic sequence in
ascending order, if dir = ASCENDING, and in descending order
otherwise. The sequence to be sorted starts at index position lo,
the number of elements is cnt.
**/
__attribute__((always_inline)) static inline void
bitonic_merge(int lo, int cnt, int dir) {
int k = cnt / 2;
int i;
__pragma_loopbound(0, 16);
for (i = lo; i < lo + k; i++)
bitonic_compare(i, i + k, dir);
if (k > 1) {
bitonic_merge(lo, k, dir);
bitonic_merge(lo + k, k, dir);
}
}
/** Procedure bitonicSort first produces a bitonic sequence by
recursively sorting its two halves in opposite directions, and then
calls bitonicMerge.
**/
__attribute__((always_inline)) static inline void
bitonic_sort(int lo, int cnt, int dir) {
int k = cnt;
k /= 2;
_Pragma("marker recMerge")
if (cnt > 1) {
bitonic_sort(lo, k, bitonic_ASCENDING);
bitonic_sort(lo + k, k, bitonic_DESCENDING);
}
bitonic_merge(lo, cnt, dir);
_Pragma("flowrestriction 1*bitonicMerge <= 31*recMerge")
return;
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bitonic_main(void) {
int i;
/** When called with parameters lo = 0, cnt = a.length() and dir =
ASCENDING, procedure bitonicSort sorts the whole array a. **/
_Pragma("marker recSort") bitonic_sort(0, 32, bitonic_ASCENDING);
_Pragma("flowrestriction 1*bitonicSort <= 63*recSort")
/** Loop through array, printing out each element **/
__pragma_loopbound(32, 32);
for (i = 0; i < 32; i++) {
}
}
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
bitonic_init();
bitonic_main();
return (bitonic_return());
}

View File

@ -0,0 +1,21 @@
The MIT License
Copyright (c) <year> <copyright holders>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@ -0,0 +1,25 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(bsort)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/bsort.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/bsort.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,42 @@
File: bsort.c
Original provenience: Mälardalen benchmark suite,
Source: http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bsort100/bsort100.c
2017-04-18:
- Annotated bsort_main as entry-point for timing analysis.
2016-04-20:
- Check upon call of bsort_return that bsort_Array is sorted.
2016-03-15:
- Renamed file from bsort100.c to bsort.c.
- Introduced comments to split file in sections for forward
declarations, global variables, initialization-related and
return-value-related functions, core benchmark functions, and
main routine.
- Added functions bsort_init and bsort_main that call
bsort_Initialize and bsort_BubbleSort, respectively.
- Added function bsort_return that handles the return value.
- Renamed function Initialize to bsort_Initialize.
- Renamed function BubbleSort to bsort_BubbleSort.
- Replaced preprocessor defines NUMELEMS and MAXDIM by unificated
define bsort_SIZE, fixed bug that caused the first element of the
array to be ignored during sorting.
- Replaced preprocessor defines TRUE, FALSE, WORSTCASE and
KNOWN_VALUE by their values.
- Fixed compiler warning "unused variable 'Seed'" by removing the
offending variable.
- Fixed compiler warning "no previous extern declaration for
non-static variable" by making global variables static.
- Fixed compiler warning "unused variable 'LastIndex'" by removing
the offending variable.
- Fixed compiler warning "declaration shadows a variable in the
global scope" by renaming global variable Array to bsort_Array.
- Fixed compiler warning "// comments are not allowed in this
language" by removing dead code.
- Replaced comment describing purpose of benchmark with generic
TACLeBench header.
- Applied TACLeBench formatting rules via
astyle --options=doc/example/astylerc.txt
- Tested conformance to C90 via
clang -fsyntax-only -Weverything -Wno-unknown-pragmas -pedantic -std=c90

View File

@ -0,0 +1,132 @@
/*
This program is part of the TACLeBench benchmark suite.
Version 2.0
Name: bsort
Author: unknown
Function: A program for testing the basic loop constructs,
integer comparisons, and simple array handling by
sorting 100 integers
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bsort100/bsort100.c
Original name: bsort100
Changes: See ChangeLog.txt
License: May be used, modified, and re-distributed freely.
*/
/*
Forward declaration of functions
*/
void bsort_init( void );
void bsort_main( void );
int bsort_return( void );
int bsort_Initialize( int Array[] );
int bsort_BubbleSort( int Array[] );
/*
Declaration of global variables
*/
#define bsort_SIZE 100
static int bsort_Array[ bsort_SIZE ];
/*
Initialization- and return-value-related functions
*/
/* Initializes given array with randomly generated integers. */
int bsort_Initialize( int Array[] )
{
int Index;
_Pragma( "loopbound min 100 max 100" )
for ( Index = 0; Index < bsort_SIZE; Index ++ )
Array[ Index ] = ( Index + 1 ) * -1;
return 0;
}
void bsort_init( void )
{
bsort_Initialize( bsort_Array );
}
int bsort_return( void )
{
int Sorted = 1;
int Index;
_Pragma( "loopbound min 99 max 99" )
for ( Index = 0; Index < bsort_SIZE - 1; Index ++ )
Sorted = Sorted && ( bsort_Array[ Index ] < bsort_Array[ Index + 1 ] );
return 1 - Sorted;
}
/*
Core benchmark functions
*/
/* Sorts an array of integers of size bsort_SIZE in ascending
order with bubble sort. */
int bsort_BubbleSort( int Array[] )
{
int Sorted = 0;
int Temp, Index, i;
_Pragma( "loopbound min 99 max 99" )
for ( i = 0; i < bsort_SIZE - 1; i ++ ) {
Sorted = 1;
_Pragma( "loopbound min 3 max 99" )
for ( Index = 0; Index < bsort_SIZE - 1; Index ++ ) {
if ( Index > bsort_SIZE - i )
break;
if ( Array[ Index ] > Array[Index + 1] ) {
Temp = Array[ Index ];
Array[ Index ] = Array[ Index + 1 ];
Array[ Index + 1 ] = Temp;
Sorted = 0;
}
}
if ( Sorted )
break;
}
return 0;
}
void _Pragma( "entrypoint" ) bsort_main( void )
{
bsort_BubbleSort( bsort_Array );
}
/*
Main function
*/
int main( void )
{
bsort_init();
bsort_main();
return bsort_return();
}

Binary file not shown.

View File

@ -0,0 +1,246 @@
(module $bsort.wasm
(type (;0;) (func (param i32 i32)))
(type (;1;) (func))
(type (;2;) (func (result i32)))
(import "__pragma" "loopbound" (func $__pragma_loopbound (type 0)))
(func $__wasm_apply_data_relocs (type 1))
(func $bsort_main (type 1)
(local i32 i32 i32 i32 i32 i32 i32 i32)
i32.const 99
i32.const 99
call $__pragma_loopbound
i32.const 0
local.set 0
loop ;; label = @1
i32.const 3
i32.const 99
call $__pragma_loopbound
i32.const 100
local.get 0
i32.sub
local.set 1
i32.const 0
i32.load offset=1024
local.set 2
i32.const 0
local.set 3
i32.const 1
local.set 4
block ;; label = @2
block ;; label = @3
loop ;; label = @4
block ;; label = @5
block ;; label = @6
local.get 2
local.get 3
i32.const 1
i32.add
local.tee 5
i32.const 2
i32.shl
i32.const 1024
i32.add
i32.load
local.tee 6
i32.gt_s
br_if 0 (;@6;)
local.get 3
local.set 7
local.get 5
local.set 3
br 1 (;@5;)
end
local.get 3
i32.const 2
i32.shl
i32.const 1024
i32.add
local.set 7
loop ;; label = @6
local.get 7
local.get 6
i32.store
local.get 7
i32.const 4
i32.add
local.tee 6
local.get 2
i32.store
local.get 3
i32.const 97
i32.gt_u
br_if 3 (;@3;)
local.get 3
local.get 1
i32.ge_u
br_if 3 (;@3;)
local.get 3
i32.const 1
i32.add
local.set 3
local.get 7
i32.const 8
i32.add
local.set 5
local.get 6
local.set 7
local.get 2
local.get 5
i32.load
local.tee 6
i32.gt_s
br_if 0 (;@6;)
end
i32.const 0
local.set 4
local.get 3
local.set 7
local.get 3
i32.const 1
i32.add
local.set 3
end
local.get 6
local.set 2
block ;; label = @5
local.get 7
i32.const 97
i32.gt_u
br_if 0 (;@5;)
local.get 7
local.get 1
i32.lt_u
br_if 1 (;@4;)
end
end
local.get 4
br_if 1 (;@2;)
local.get 0
i32.const 1
i32.add
local.tee 0
i32.const 99
i32.ne
br_if 2 (;@1;)
br 1 (;@2;)
end
local.get 0
i32.const 1
i32.add
local.tee 0
i32.const 99
i32.ne
br_if 1 (;@1;)
end
end)
(func $__original_main (type 2) (result i32)
(local i32 i32)
i32.const 100
i32.const 100
call $__pragma_loopbound
i32.const 1024
local.set 0
i32.const -5
local.set 1
loop ;; label = @1
local.get 0
i32.const 16
i32.add
local.get 1
i32.store
local.get 0
i32.const 12
i32.add
local.get 1
i32.const 1
i32.add
i32.store
local.get 0
i32.const 8
i32.add
local.get 1
i32.const 2
i32.add
i32.store
local.get 0
i32.const 4
i32.add
local.get 1
i32.const 3
i32.add
i32.store
local.get 0
local.get 1
i32.const 4
i32.add
i32.store
local.get 0
i32.const 20
i32.add
local.set 0
local.get 1
i32.const -5
i32.add
local.tee 1
i32.const -105
i32.ne
br_if 0 (;@1;)
end
call $bsort_main
i32.const 99
i32.const 99
call $__pragma_loopbound
i32.const 0
local.set 0
i32.const 1
local.set 1
loop ;; label = @1
block ;; label = @2
block ;; label = @3
local.get 1
br_if 0 (;@3;)
local.get 0
i32.const 1
i32.add
local.set 0
i32.const 0
local.set 1
br 1 (;@2;)
end
local.get 0
i32.const 2
i32.shl
i32.const 1024
i32.add
i32.load
local.get 0
i32.const 1
i32.add
local.tee 0
i32.const 2
i32.shl
i32.const 1024
i32.add
i32.load
i32.lt_s
local.set 1
end
local.get 0
i32.const 99
i32.ne
br_if 0 (;@1;)
end
local.get 1
i32.const 1
i32.xor)
(table (;0;) 1 1 funcref)
(memory (;0;) 1)
(global $__stack_pointer (mut i32) (i32.const 5520))
(global (;1;) i32 (i32.const 1424))
(global (;2;) i32 (i32.const 5520))
(export "memory" (memory 0))
(export "__wasm_apply_data_relocs" (func $__wasm_apply_data_relocs))
(export "entrypoint" (func $bsort_main))
(export "main" (func $__original_main))
(export "__data_end" (global 1))
(export "__heap_base" (global 2)))

View File

@ -0,0 +1,130 @@
/*
This program is part of the TACLeBench benchmark suite.
Version 2.0
Name: bsort
Author: unknown
Function: A program for testing the basic loop constructs,
integer comparisons, and simple array handling by
sorting 100 integers
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bsort100/bsort100.c
Original name: bsort100
Changes: See ChangeLog.txt
License: May be used, modified, and re-distributed freely.
*/
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
void bsort_init(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bsort_main(void);
int bsort_return(void);
int bsort_Initialize(int Array[]);
int bsort_BubbleSort(int Array[]);
/*
Declaration of global variables
*/
#define bsort_SIZE 100
static int bsort_Array[bsort_SIZE];
/*
Initialization- and return-value-related functions
*/
/* Initializes given array with randomly generated integers. */
int
bsort_Initialize(int Array[]) {
int Index;
__pragma_loopbound(100, 100);
for (Index = 0; Index < bsort_SIZE; Index++)
Array[Index] = (Index + 1) * -1;
return 0;
}
void
bsort_init(void) {
bsort_Initialize(bsort_Array);
}
int
bsort_return(void) {
int Sorted = 1;
int Index;
__pragma_loopbound(99, 99);
for (Index = 0; Index < bsort_SIZE - 1; Index++)
Sorted = Sorted && (bsort_Array[Index] < bsort_Array[Index + 1]);
return 1 - Sorted;
}
/*
Core benchmark functions
*/
/* Sorts an array of integers of size bsort_SIZE in ascending
order with bubble sort. */
int
bsort_BubbleSort(int Array[]) {
int Sorted = 0;
int Temp, Index, i;
__pragma_loopbound(99, 99);
for (i = 0; i < bsort_SIZE - 1; i++) {
Sorted = 1;
__pragma_loopbound(3, 99);
for (Index = 0; Index < bsort_SIZE - 1; Index++) {
if (Index > bsort_SIZE - i)
break;
if (Array[Index] > Array[Index + 1]) {
Temp = Array[Index];
Array[Index] = Array[Index + 1];
Array[Index + 1] = Temp;
Sorted = 0;
}
}
if (Sorted)
break;
}
return 0;
}
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bsort_main(void) {
bsort_BubbleSort(bsort_Array);
}
/*
Main function
*/
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
bsort_init();
bsort_main();
return bsort_return();
}

View File

@ -0,0 +1,136 @@
/*
This program is part of the TACLeBench benchmark suite.
Version 2.0
Name: bsort
Author: unknown
Function: A program for testing the basic loop constructs,
integer comparisons, and simple array handling by
sorting 100 integers
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/bsort100/bsort100.c
Original name: bsort100
Changes: See ChangeLog.txt
License: May be used, modified, and re-distributed freely.
*/
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
__attribute__((always_inline)) static inline void bsort_init(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bsort_main(void);
__attribute__((always_inline)) static inline int bsort_return(void);
__attribute__((always_inline)) static inline int bsort_Initialize(int Array[]);
__attribute__((always_inline)) static inline int bsort_BubbleSort(int Array[]);
/*
Declaration of global variables
*/
#define bsort_SIZE 100
static int bsort_Array[bsort_SIZE];
/*
Initialization- and return-value-related functions
*/
/* Initializes given array with randomly generated integers. */
__attribute__((always_inline)) static inline int
bsort_Initialize(int Array[]) {
int Index;
__pragma_loopbound(100, 100);
for (Index = 0; Index < bsort_SIZE; Index++)
Array[Index] = (Index + 1) * -1;
return 0;
}
__attribute__((always_inline)) static inline void
bsort_init(void) {
bsort_Initialize(bsort_Array);
}
__attribute__((always_inline)) static inline int
bsort_return(void) {
int Sorted = 1;
int Index;
__pragma_loopbound(99, 99);
for (Index = 0; Index < bsort_SIZE - 1; Index++)
Sorted = Sorted && (bsort_Array[Index] < bsort_Array[Index + 1]);
return 1 - Sorted;
}
/*
Core benchmark functions
*/
/* Sorts an array of integers of size bsort_SIZE in ascending
order with bubble sort. */
__attribute__((always_inline)) static inline int
bsort_BubbleSort(int Array[]) {
int Sorted = 0;
int Temp, Index, i;
__pragma_loopbound(99, 99);
for (i = 0; i < bsort_SIZE - 1; i++) {
Sorted = 1;
__pragma_loopbound(3, 99);
for (Index = 0; Index < bsort_SIZE - 1; Index++) {
if (Index > bsort_SIZE - i)
break;
if (Array[Index] > Array[Index + 1]) {
Temp = Array[Index];
Array[Index] = Array[Index + 1];
Array[Index + 1] = Temp;
Sorted = 0;
}
}
if (Sorted)
break;
}
return 0;
}
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
bsort_main(void) {
bsort_BubbleSort(bsort_Array);
}
/*
Main function
*/
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
bsort_init();
bsort_main();
return bsort_return();
}

View File

@ -0,0 +1,25 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(complex_updates)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/complex_updates.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/complex_updates.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,27 @@
File: complex_updates.c
Original provenience: DSP-Stone
2016-03-02:
- Rename n_complex_updates_float to n_complex_updates
- Add generic TACLeBench header
- Prefix global function with benchmark name
- Avoid accepting arbitrary number of parameters
- Introduce return statement
- Make A, B, C, D global variables
- Split code into n_complex_updates_init and n_complex_updates_main
2016-04-25:
- Rename to complex_updates in order to shorten prefixes
- Remove second call of pin_down, since this was originally used as a border for
constant propagation
- Move pin_down call into init function
- Add operation on input data with volatile variable to completely prevent
constant propagation
- Prefix all global symbols with benchmark name
- Add calculation of checksum on result data, which is used in return statement
- Apply code formatting with clang-format (manually move loop-bound annotation
into separate line and align assignments in complex_updates_main)
2016-04-25:
- Replace usages of macros by their expansions:
STORAGE_CLASS => register, TYPE => float
2016-05-25:
- Apply code formatting with astyle

View File

@ -0,0 +1,136 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: complex_updates
Author: Juan Martinez Velarde
Function: complex_updates is a program for filter benchmarking.
This program performs n complex updates of the form
D(i) = C(i) + A(i)*B(i),
where A(i), B(i), C(i) and D(i) are complex numbers,
and i = 1,...,N
A(i) = Ar(i) + j Ai(i)
B(i) = Br(i) + j Bi(i)
C(i) = Cr(i) + j Ci(i)
D(i) = C(i) + A(i)*B(i) = Dr(i) + j Di(i)
=> Dr(i) = Cr(i) + Ar(i)*Br(i) - Ai(i)*Bi(i)
=> Di(i) = Ci(i) + Ar(i)*Bi(i) + Ai(i)*Br(i)
Source: DSP-Stone
http://www.ice.rwth-aachen.de/research/tools-projects/entry/detail/dspstone/
Original name: n_complex_updates_float
Changes: no major functional changes
License: may be used, modified, and re-distributed freely
*/
#define N 16
/*
Forward declaration of functions
*/
void complex_updates_pin_down( float *pa, float *pb, float *pc, float *pd );
void complex_updates_init( void );
void complex_updates_main( void );
int main( void );
/*
Declaration of global variables
*/
float complex_updates_A[ 2 * N ], complex_updates_B[ 2 * N ],
complex_updates_C[ 2 * N ], complex_updates_D[ 2 * N ];
/*
Initialization- and return-value-related functions
*/
void complex_updates_init( void )
{
int i;
volatile float x = 0;
complex_updates_pin_down( &complex_updates_A[ 0 ], &complex_updates_B[ 0 ],
&complex_updates_C[ 0 ], &complex_updates_D[ 0 ] );
/* avoid constant propagation */
_Pragma( "loopbound min 16 max 16" )
for ( i = 0 ; i < N ; i++ ) {
complex_updates_A[ i ] += x;
complex_updates_B[ i ] += x;
complex_updates_C[ i ] += x;
complex_updates_D[ i ] += x;
}
}
void complex_updates_pin_down( float *pa, float *pb, float *pc, float *pd )
{
register int i;
_Pragma( "loopbound min 16 max 16" )
for ( i = 0; i < N; i++ ) {
*pa++ = 2;
*pa++ = 1;
*pb++ = 2;
*pb++ = 5;
*pc++ = 3;
*pc++ = 4;
*pd++ = 0;
*pd++ = 0;
}
}
int complex_updates_return( void )
{
float check_sum = 0;
int i;
_Pragma( "loopbound min 16 max 16" )
for ( i = 0; i < N; i++ )
check_sum += complex_updates_D[ i ];
return ( check_sum != 144.0f );
}
/*
Main functions
*/
void _Pragma( "entrypoint" ) complex_updates_main( void )
{
register float *p_a = &complex_updates_A[ 0 ], *p_b = &complex_updates_B[ 0 ];
register float *p_c = &complex_updates_C[ 0 ], *p_d = &complex_updates_D[ 0 ];
int i;
_Pragma( "loopbound min 16 max 16" )
for ( i = 0 ; i < N ; i++, p_a++ ) {
*p_d = *p_c++ + *p_a++ * *p_b++ ;
*p_d++ -= *p_a * *p_b-- ;
*p_d = *p_c++ + *p_a-- * *p_b++ ;
*p_d++ += *p_a++ * *p_b++ ;
}
}
int main( void )
{
complex_updates_init();
complex_updates_main();
return complex_updates_return();
}

View File

@ -0,0 +1,889 @@
(module $complex_updates.wasm
(type (;0;) (func (param i32 i32)))
(type (;1;) (func))
(type (;2;) (func (param i32 i32 i32 i32)))
(type (;3;) (func (result i32)))
(import "__pragma" "loopbound" (func $__pragma_loopbound (type 0)))
(func $__wasm_apply_data_relocs (type 1))
(func $complex_updates_pin_down (type 2) (param i32 i32 i32 i32)
i32.const 16
i32.const 16
call $__pragma_loopbound
local.get 0
i64.const 4575657222482165760
i64.store align=4
local.get 1
i64.const 4656722015774834688
i64.store align=4
local.get 2
i64.const 4647714816524288000
i64.store align=4
local.get 3
i64.const 0
i64.store align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=8 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=8 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=8 align=4
local.get 3
i64.const 0
i64.store offset=8 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=16 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=16 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=16 align=4
local.get 3
i64.const 0
i64.store offset=16 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=24 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=24 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=24 align=4
local.get 3
i64.const 0
i64.store offset=24 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=32 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=32 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=32 align=4
local.get 3
i64.const 0
i64.store offset=32 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=40 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=40 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=40 align=4
local.get 3
i64.const 0
i64.store offset=40 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=48 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=48 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=48 align=4
local.get 3
i64.const 0
i64.store offset=48 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=56 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=56 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=56 align=4
local.get 3
i64.const 0
i64.store offset=56 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=64 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=64 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=64 align=4
local.get 3
i64.const 0
i64.store offset=64 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=72 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=72 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=72 align=4
local.get 3
i64.const 0
i64.store offset=72 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=80 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=80 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=80 align=4
local.get 3
i64.const 0
i64.store offset=80 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=88 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=88 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=88 align=4
local.get 3
i64.const 0
i64.store offset=88 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=96 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=96 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=96 align=4
local.get 3
i64.const 0
i64.store offset=96 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=104 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=104 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=104 align=4
local.get 3
i64.const 0
i64.store offset=104 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=112 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=112 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=112 align=4
local.get 3
i64.const 0
i64.store offset=112 align=4
local.get 0
i64.const 4575657222482165760
i64.store offset=120 align=4
local.get 1
i64.const 4656722015774834688
i64.store offset=120 align=4
local.get 2
i64.const 4647714816524288000
i64.store offset=120 align=4
local.get 3
i64.const 0
i64.store offset=120 align=4)
(func $complex_updates_main (type 1)
(local f32 f32 f32 f32)
i32.const 16
i32.const 16
call $__pragma_loopbound
i32.const 0
i32.const 0
f32.load offset=1024
local.tee 0
i32.const 0
f32.load offset=1152
local.tee 1
f32.mul
i32.const 0
f32.load offset=1280
f32.add
i32.const 0
f32.load offset=1028
local.tee 2
i32.const 0
f32.load offset=1156
local.tee 3
f32.mul
f32.sub
f32.store offset=1408
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1284
f32.add
f32.add
f32.store offset=1412
i32.const 0
i32.const 0
f32.load offset=1032
local.tee 0
i32.const 0
f32.load offset=1160
local.tee 1
f32.mul
i32.const 0
f32.load offset=1288
f32.add
i32.const 0
f32.load offset=1036
local.tee 2
i32.const 0
f32.load offset=1164
local.tee 3
f32.mul
f32.sub
f32.store offset=1416
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1292
f32.add
f32.add
f32.store offset=1420
i32.const 0
i32.const 0
f32.load offset=1040
local.tee 0
i32.const 0
f32.load offset=1168
local.tee 1
f32.mul
i32.const 0
f32.load offset=1296
f32.add
i32.const 0
f32.load offset=1044
local.tee 2
i32.const 0
f32.load offset=1172
local.tee 3
f32.mul
f32.sub
f32.store offset=1424
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1300
f32.add
f32.add
f32.store offset=1428
i32.const 0
i32.const 0
f32.load offset=1048
local.tee 0
i32.const 0
f32.load offset=1176
local.tee 1
f32.mul
i32.const 0
f32.load offset=1304
f32.add
i32.const 0
f32.load offset=1052
local.tee 2
i32.const 0
f32.load offset=1180
local.tee 3
f32.mul
f32.sub
f32.store offset=1432
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1308
f32.add
f32.add
f32.store offset=1436
i32.const 0
i32.const 0
f32.load offset=1056
local.tee 0
i32.const 0
f32.load offset=1184
local.tee 1
f32.mul
i32.const 0
f32.load offset=1312
f32.add
i32.const 0
f32.load offset=1060
local.tee 2
i32.const 0
f32.load offset=1188
local.tee 3
f32.mul
f32.sub
f32.store offset=1440
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1316
f32.add
f32.add
f32.store offset=1444
i32.const 0
i32.const 0
f32.load offset=1064
local.tee 0
i32.const 0
f32.load offset=1192
local.tee 1
f32.mul
i32.const 0
f32.load offset=1320
f32.add
i32.const 0
f32.load offset=1068
local.tee 2
i32.const 0
f32.load offset=1196
local.tee 3
f32.mul
f32.sub
f32.store offset=1448
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1324
f32.add
f32.add
f32.store offset=1452
i32.const 0
i32.const 0
f32.load offset=1072
local.tee 0
i32.const 0
f32.load offset=1200
local.tee 1
f32.mul
i32.const 0
f32.load offset=1328
f32.add
i32.const 0
f32.load offset=1076
local.tee 2
i32.const 0
f32.load offset=1204
local.tee 3
f32.mul
f32.sub
f32.store offset=1456
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1332
f32.add
f32.add
f32.store offset=1460
i32.const 0
i32.const 0
f32.load offset=1080
local.tee 0
i32.const 0
f32.load offset=1208
local.tee 1
f32.mul
i32.const 0
f32.load offset=1336
f32.add
i32.const 0
f32.load offset=1084
local.tee 2
i32.const 0
f32.load offset=1212
local.tee 3
f32.mul
f32.sub
f32.store offset=1464
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1340
f32.add
f32.add
f32.store offset=1468
i32.const 0
i32.const 0
f32.load offset=1088
local.tee 0
i32.const 0
f32.load offset=1216
local.tee 1
f32.mul
i32.const 0
f32.load offset=1344
f32.add
i32.const 0
f32.load offset=1092
local.tee 2
i32.const 0
f32.load offset=1220
local.tee 3
f32.mul
f32.sub
f32.store offset=1472
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1348
f32.add
f32.add
f32.store offset=1476
i32.const 0
i32.const 0
f32.load offset=1096
local.tee 0
i32.const 0
f32.load offset=1224
local.tee 1
f32.mul
i32.const 0
f32.load offset=1352
f32.add
i32.const 0
f32.load offset=1100
local.tee 2
i32.const 0
f32.load offset=1228
local.tee 3
f32.mul
f32.sub
f32.store offset=1480
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1356
f32.add
f32.add
f32.store offset=1484
i32.const 0
i32.const 0
f32.load offset=1104
local.tee 0
i32.const 0
f32.load offset=1232
local.tee 1
f32.mul
i32.const 0
f32.load offset=1360
f32.add
i32.const 0
f32.load offset=1108
local.tee 2
i32.const 0
f32.load offset=1236
local.tee 3
f32.mul
f32.sub
f32.store offset=1488
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1364
f32.add
f32.add
f32.store offset=1492
i32.const 0
i32.const 0
f32.load offset=1112
local.tee 0
i32.const 0
f32.load offset=1240
local.tee 1
f32.mul
i32.const 0
f32.load offset=1368
f32.add
i32.const 0
f32.load offset=1116
local.tee 2
i32.const 0
f32.load offset=1244
local.tee 3
f32.mul
f32.sub
f32.store offset=1496
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1372
f32.add
f32.add
f32.store offset=1500
i32.const 0
i32.const 0
f32.load offset=1120
local.tee 0
i32.const 0
f32.load offset=1248
local.tee 1
f32.mul
i32.const 0
f32.load offset=1376
f32.add
i32.const 0
f32.load offset=1124
local.tee 2
i32.const 0
f32.load offset=1252
local.tee 3
f32.mul
f32.sub
f32.store offset=1504
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1380
f32.add
f32.add
f32.store offset=1508
i32.const 0
i32.const 0
f32.load offset=1128
local.tee 0
i32.const 0
f32.load offset=1256
local.tee 1
f32.mul
i32.const 0
f32.load offset=1384
f32.add
i32.const 0
f32.load offset=1132
local.tee 2
i32.const 0
f32.load offset=1260
local.tee 3
f32.mul
f32.sub
f32.store offset=1512
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1388
f32.add
f32.add
f32.store offset=1516
i32.const 0
i32.const 0
f32.load offset=1136
local.tee 0
i32.const 0
f32.load offset=1264
local.tee 1
f32.mul
i32.const 0
f32.load offset=1392
f32.add
i32.const 0
f32.load offset=1140
local.tee 2
i32.const 0
f32.load offset=1268
local.tee 3
f32.mul
f32.sub
f32.store offset=1520
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1396
f32.add
f32.add
f32.store offset=1524
i32.const 0
i32.const 0
f32.load offset=1144
local.tee 0
i32.const 0
f32.load offset=1272
local.tee 1
f32.mul
i32.const 0
f32.load offset=1400
f32.add
i32.const 0
f32.load offset=1148
local.tee 2
i32.const 0
f32.load offset=1276
local.tee 3
f32.mul
f32.sub
f32.store offset=1528
i32.const 0
local.get 0
local.get 3
f32.mul
local.get 2
local.get 1
f32.mul
i32.const 0
f32.load offset=1404
f32.add
f32.add
f32.store offset=1532)
(func $__original_main (type 3) (result i32)
(local i32 i32 i32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32 f32)
global.get $__stack_pointer
i32.const 16
i32.sub
local.tee 0
global.set $__stack_pointer
local.get 0
i32.const 0
i32.store offset=12
i32.const 1024
i32.const 1152
i32.const 1280
i32.const 1408
call $complex_updates_pin_down
i32.const 16
i32.const 16
call $__pragma_loopbound
i32.const -64
local.set 1
loop ;; label = @1
local.get 1
i32.const 1088
i32.add
local.tee 2
local.get 2
f32.load
local.get 0
f32.load offset=12
f32.add
f32.store
local.get 1
i32.const 1216
i32.add
local.tee 2
local.get 2
f32.load
local.get 0
f32.load offset=12
f32.add
f32.store
local.get 1
i32.const 1344
i32.add
local.tee 2
local.get 2
f32.load
local.get 0
f32.load offset=12
f32.add
f32.store
local.get 1
i32.const 1472
i32.add
local.tee 2
local.get 2
f32.load
local.get 0
f32.load offset=12
f32.add
f32.store
local.get 1
i32.const 4
i32.add
local.tee 1
br_if 0 (;@1;)
end
call $complex_updates_main
i32.const 16
i32.const 16
call $__pragma_loopbound
i32.const 0
f32.load offset=1408
local.set 3
i32.const 0
f32.load offset=1412
local.set 4
i32.const 0
f32.load offset=1416
local.set 5
i32.const 0
f32.load offset=1420
local.set 6
i32.const 0
f32.load offset=1424
local.set 7
i32.const 0
f32.load offset=1428
local.set 8
i32.const 0
f32.load offset=1432
local.set 9
i32.const 0
f32.load offset=1436
local.set 10
i32.const 0
f32.load offset=1440
local.set 11
i32.const 0
f32.load offset=1444
local.set 12
i32.const 0
f32.load offset=1448
local.set 13
i32.const 0
f32.load offset=1452
local.set 14
i32.const 0
f32.load offset=1456
local.set 15
i32.const 0
f32.load offset=1460
local.set 16
i32.const 0
f32.load offset=1464
local.set 17
i32.const 0
f32.load offset=1468
local.set 18
local.get 0
i32.const 16
i32.add
global.set $__stack_pointer
local.get 18
local.get 17
local.get 16
local.get 15
local.get 14
local.get 13
local.get 12
local.get 11
local.get 10
local.get 9
local.get 8
local.get 7
local.get 6
local.get 5
local.get 4
local.get 3
f32.const 0x0p+0 (;=0;)
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.add
f32.const 0x1.2p+7 (;=144;)
f32.ne)
(table (;0;) 1 1 funcref)
(memory (;0;) 1)
(global $__stack_pointer (mut i32) (i32.const 5632))
(global (;1;) i32 (i32.const 1536))
(global (;2;) i32 (i32.const 5632))
(export "memory" (memory 0))
(export "__wasm_apply_data_relocs" (func $__wasm_apply_data_relocs))
(export "entrypoint" (func $complex_updates_main))
(export "main" (func $__original_main))
(export "__data_end" (global 1))
(export "__heap_base" (global 2)))

View File

@ -0,0 +1,135 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: complex_updates
Author: Juan Martinez Velarde
Function: complex_updates is a program for filter benchmarking.
This program performs n complex updates of the form
D(i) = C(i) + A(i)*B(i),
where A(i), B(i), C(i) and D(i) are complex numbers,
and i = 1,...,N
A(i) = Ar(i) + j Ai(i)
B(i) = Br(i) + j Bi(i)
C(i) = Cr(i) + j Ci(i)
D(i) = C(i) + A(i)*B(i) = Dr(i) + j Di(i)
=> Dr(i) = Cr(i) + Ar(i)*Br(i) - Ai(i)*Bi(i)
=> Di(i) = Ci(i) + Ar(i)*Bi(i) + Ai(i)*Br(i)
Source: DSP-Stone
http://www.ice.rwth-aachen.de/research/tools-projects/entry/detail/dspstone/
Original name: n_complex_updates_float
Changes: no major functional changes
License: may be used, modified, and re-distributed freely
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
#define N 16
/*
Forward declaration of functions
*/
void complex_updates_pin_down(float *pa, float *pb, float *pc, float *pd);
void complex_updates_init(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
complex_updates_main(void);
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
/*
Declaration of global variables
*/
float complex_updates_A[2 * N], complex_updates_B[2 * N],
complex_updates_C[2 * N], complex_updates_D[2 * N];
/*
Initialization- and return-value-related functions
*/
void
complex_updates_init(void) {
int i;
volatile float x = 0;
complex_updates_pin_down(&complex_updates_A[0], &complex_updates_B[0],
&complex_updates_C[0], &complex_updates_D[0]);
/* avoid constant propagation */
__pragma_loopbound(16, 16);
for (i = 0; i < N; i++) {
complex_updates_A[i] += x;
complex_updates_B[i] += x;
complex_updates_C[i] += x;
complex_updates_D[i] += x;
}
}
void
complex_updates_pin_down(float *pa, float *pb, float *pc, float *pd) {
register int i;
__pragma_loopbound(16, 16);
for (i = 0; i < N; i++) {
*pa++ = 2;
*pa++ = 1;
*pb++ = 2;
*pb++ = 5;
*pc++ = 3;
*pc++ = 4;
*pd++ = 0;
*pd++ = 0;
}
}
int
complex_updates_return(void) {
float check_sum = 0;
int i;
__pragma_loopbound(16, 16);
for (i = 0; i < N; i++)
check_sum += complex_updates_D[i];
return (check_sum != 144.0f);
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
complex_updates_main(void) {
register float *p_a = &complex_updates_A[0], *p_b = &complex_updates_B[0];
register float *p_c = &complex_updates_C[0], *p_d = &complex_updates_D[0];
int i;
__pragma_loopbound(16, 16);
for (i = 0; i < N; i++, p_a++) {
*p_d = *p_c++ + *p_a++ * *p_b++;
*p_d++ -= *p_a * *p_b--;
*p_d = *p_c++ + *p_a-- * *p_b++;
*p_d++ += *p_a++ * *p_b++;
}
}
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
complex_updates_init();
complex_updates_main();
return complex_updates_return();
}

View File

@ -0,0 +1,144 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: complex_updates
Author: Juan Martinez Velarde
Function: complex_updates is a program for filter benchmarking.
This program performs n complex updates of the form
D(i) = C(i) + A(i)*B(i),
where A(i), B(i), C(i) and D(i) are complex numbers,
and i = 1,...,N
A(i) = Ar(i) + j Ai(i)
B(i) = Br(i) + j Bi(i)
C(i) = Cr(i) + j Ci(i)
D(i) = C(i) + A(i)*B(i) = Dr(i) + j Di(i)
=> Dr(i) = Cr(i) + Ar(i)*Br(i) - Ai(i)*Bi(i)
=> Di(i) = Ci(i) + Ar(i)*Bi(i) + Ai(i)*Br(i)
Source: DSP-Stone
http://www.ice.rwth-aachen.de/research/tools-projects/entry/detail/dspstone/
Original name: n_complex_updates_float
Changes: no major functional changes
License: may be used, modified, and re-distributed freely
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
#define N 16
/*
Forward declaration of functions
*/
__attribute__((always_inline)) static inline void
complex_updates_pin_down(float *pa, float *pb, float *pc, float *pd);
__attribute__((always_inline)) static inline void complex_updates_init(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
complex_updates_main(void);
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void);
/*
Declaration of global variables
*/
float complex_updates_A[2 * N], complex_updates_B[2 * N],
complex_updates_C[2 * N], complex_updates_D[2 * N];
/*
Initialization- and return-value-related functions
*/
__attribute__((always_inline)) static inline void
complex_updates_init(void) {
int i;
volatile float x = 0;
complex_updates_pin_down(&complex_updates_A[0], &complex_updates_B[0],
&complex_updates_C[0], &complex_updates_D[0]);
/* avoid constant propagation */
__pragma_loopbound(16, 16);
for (i = 0; i < N; i++) {
complex_updates_A[i] += x;
complex_updates_B[i] += x;
complex_updates_C[i] += x;
complex_updates_D[i] += x;
}
}
__attribute__((always_inline)) static inline void
complex_updates_pin_down(float *pa, float *pb, float *pc, float *pd) {
register int i;
__pragma_loopbound(16, 16);
for (i = 0; i < N; i++) {
*pa++ = 2;
*pa++ = 1;
*pb++ = 2;
*pb++ = 5;
*pc++ = 3;
*pc++ = 4;
*pd++ = 0;
*pd++ = 0;
}
}
__attribute__((always_inline)) static inline int
complex_updates_return(void) {
float check_sum = 0;
int i;
__pragma_loopbound(16, 16);
for (i = 0; i < N; i++)
check_sum += complex_updates_D[i];
return (check_sum != 144.0f);
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
complex_updates_main(void) {
register float *p_a = &complex_updates_A[0], *p_b = &complex_updates_B[0];
register float *p_c = &complex_updates_C[0], *p_d = &complex_updates_D[0];
int i;
__pragma_loopbound(16, 16);
for (i = 0; i < N; i++, p_a++) {
*p_d = *p_c++ + *p_a++ * *p_b++;
*p_d++ -= *p_a * *p_b--;
*p_d = *p_c++ + *p_a-- * *p_b++;
*p_d++ += *p_a++ * *p_b++;
}
}
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
complex_updates_init();
complex_updates_main();
return complex_updates_return();
}

View File

@ -0,0 +1,26 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(cosf)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/cosf.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/cosf.c"
"generated/modified_sources/default/wcclibm.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,79 @@
Original provenience: MiBench benchmark suite,
http://wwweb.eecs.umich.edu/mibench
2016-02-09:
- Added TACLeBench header
- Renamed benchmark from 'basicmath_small' to 'basicmath'
- Fixed a typo in code comments: 'soem' -> 'some'
- Removed unused variable 'n' from the main funcion
- Added variable 'double Y' to the main function and accumulated the results of
'deg2rad(X)' and 'rad2deg(X)' in this variable so that the compiler warning
'statement with no effect' is fixed.
- Removed conditionally compiled main (test) function from isqrt.c
- Removed conditionally compiled main (test) function from cubic.c
- Removed commented-out code
- Removed unused function, variable, macro and type declarations, structs and
unions
- Removed seemingly unnecessary empty lines
- Renamed memcpy.t to basicmath_libc.c
- Removed unused files:
rad2deg.c
sniptype.h
sniptype.h
- Created basicmath_libc.h and put declaration of basicmath_memcpy() in it
- Reorganized snipmath.h so that the following are in the given order just
after the header
- includes
- declarations of functions
- Reorganized sniptype.h so that the following are in the given order just
after the header
- macro definitions
- type definitions
- Removed duplicated copyright information from wcclibm.c
- Removed __STDC__ checks from wcclibm.c and used only ANSI style function
arguments
- Removed 'last modified' comments from files
- Removed mention 'use __kernel_rem_pio2f()' from comments of function
__ieee754_rem_pio2f() since it doesn't really use it.
- Removed math functions specialization macros from wcclibm.h and updated call
sites with explicit nameks of the functions.
- Removed '#define double float' from wcclibm.h and replaced all 'double's
with 'float's in the benchmark
- Added a new main function that calls the old main function
- Annotated basicmath_main() as the entry point of the analysis
- Applied code formatting according to the following rules
- Lines shall not be wider than 80 characters; whenever possible, appropriate
line breaks shall be inserted to keep lines below 80 characters
- Indentation is done using whitespaces only, no tabs. Code is indented by
two whitespaces
- Two empty lines are put between any two functions
- In non-empty lists or index expressions, opening '(' and '[' are followed by
one whitespace, closing ')' and ']' are preceded by one whitespace
- In comma- or colon-separated argument lists, one whitespace is put after
each comma/colon
- Names of functions and global variables all start with a benchmark-specific
prefix (here: statemate_) followed by lowercase letter
- For pointer types, one whitespace is put before the '*'
- Operators within expressions shall be preceded and followed by one
whitespace
- Code of then- and else-parts of if-then-else statements shall be put in
separate lines, not in the same lines as the if-condition or the keyword
"else"
- Opening braces '{' denoting the beginning of code for some if-else or loop
body shall be put at the end of the same line where the keywords "if",
"else", "for", "while" etc. occur
2017-06-27
- Introduce basicmath_init and basicmath_return functions.
- Add prefix basicmath_ to global variables.
- Introduce dummy initialization in ieee754_rem_pio2f to please linter.
2017-07-10
- Fix possible stack buffer overflow caused by sizeof of incorrect type.
2019-03-07
-split basicmath into seperate files
-Add TACLeBench Header
-Add cosf.c as further benchmark
-put each benchmark into a seperate folder
-adjust the code formatting to the common TACLeBench code style

View File

@ -0,0 +1,86 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: cosf
Author: Dustin Green
Function: cosf performs calculations of the cosinus function
Source:
Original name:
Changes:
License: this code is FREE with no restrictions
*/
#include "wcclibm.h"
/*
Forward declaration of functions
*/
void cosf_init( void );
void cosf_main( void );
int cosf_return( void );
int main( void );
/*
Declaration of global variables
*/
float cosf_solutions;
/*
Initialization function
*/
void cosf_init( void )
{
cosf_solutions = 0.0f;
}
/*
Return function
*/
int cosf_return( void )
{
int temp = cosf_solutions;
if ( temp == -4 )
return 0;
else
return -1;
}
/*
Main functions
*/
void _Pragma( "entrypoint" ) cosf_main( void )
{
float i;
_Pragma( "loopbound min 100 max 100" )
for ( i = 0.0f; i < 10; i += 0.1f )
cosf_solutions += basicmath___cosf( i );
}
int main( void )
{
cosf_init();
cosf_main();
return cosf_return();
}

Binary file not shown.

View File

@ -0,0 +1,918 @@
(module $cosf.wasm
(type (;0;) (func (param i32 i32)))
(type (;1;) (func))
(type (;2;) (func (result i32)))
(type (;3;) (func (param f32 i32) (result i32)))
(type (;4;) (func (param f32) (result f32)))
(import "__pragma" "loopbound" (func $__pragma_loopbound (type 0)))
(func $__wasm_apply_data_relocs (type 1))
(func $cosf_main (type 1)
(local f32)
i32.const 100
i32.const 100
call $__pragma_loopbound
f32.const 0x0p+0 (;=0;)
local.set 0
loop ;; label = @1
i32.const 0
local.get 0
call $basicmath___cosf
i32.const 0
f32.load offset=1152
f32.add
f32.store offset=1152
local.get 0
f32.const 0x1.99999ap-4 (;=0.1;)
f32.add
local.tee 0
f32.const 0x1.4p+3 (;=10;)
f32.lt
br_if 0 (;@1;)
end)
(func $__original_main (type 2) (result i32)
(local f32 i32)
i32.const 0
i32.const 0
i32.store offset=1152
call $cosf_main
block ;; label = @1
block ;; label = @2
i32.const 0
f32.load offset=1152
local.tee 0
f32.abs
f32.const 0x1p+31 (;=2.14748e+09;)
f32.lt
i32.eqz
br_if 0 (;@2;)
local.get 0
i32.trunc_f32_s
local.set 1
br 1 (;@1;)
end
i32.const -2147483648
local.set 1
end
i32.const -1
i32.const 0
local.get 1
i32.const -4
i32.ne
select)
(func $basicmath___ieee754_rem_pio2f (type 3) (param f32 i32) (result i32)
(local f32 i32 i32 i32 f32 f32 f32)
block ;; label = @1
local.get 0
f32.abs
local.tee 2
i32.reinterpret_f32
local.tee 3
i32.const 1061752792
i32.gt_u
br_if 0 (;@1;)
local.get 1
i32.const 0
i32.store offset=4
local.get 1
local.get 0
f32.store
i32.const 0
return
end
local.get 0
i32.reinterpret_f32
local.set 4
block ;; label = @1
local.get 3
i32.const 1075235811
i32.gt_u
br_if 0 (;@1;)
local.get 3
i32.const 2147483632
i32.and
local.set 3
block ;; label = @2
local.get 4
i32.const 1
i32.lt_s
br_if 0 (;@2;)
local.get 0
f32.const -0x1.921fp+0 (;=-1.57079;)
f32.add
local.set 0
block ;; label = @3
local.get 3
i32.const 1070141392
i32.eq
br_if 0 (;@3;)
local.get 1
local.get 0
f32.const -0x1.6a8886p-17 (;=-1.08043e-05;)
f32.add
local.tee 2
f32.store
local.get 1
local.get 0
local.get 2
f32.sub
f32.const -0x1.6a8886p-17 (;=-1.08043e-05;)
f32.add
f32.store offset=4
i32.const 1
return
end
local.get 1
local.get 0
f32.const -0x1.6a88p-17 (;=-1.08043e-05;)
f32.add
local.tee 0
f32.const -0x1.0b461p-34 (;=-6.0771e-11;)
f32.add
local.tee 2
f32.store
local.get 1
local.get 0
local.get 2
f32.sub
f32.const -0x1.0b461p-34 (;=-6.0771e-11;)
f32.add
f32.store offset=4
i32.const 1
return
end
local.get 0
f32.const 0x1.921fp+0 (;=1.57079;)
f32.add
local.set 0
block ;; label = @2
local.get 3
i32.const 1070141392
i32.eq
br_if 0 (;@2;)
local.get 1
local.get 0
f32.const 0x1.6a8886p-17 (;=1.08043e-05;)
f32.add
local.tee 2
f32.store
local.get 1
local.get 0
local.get 2
f32.sub
f32.const 0x1.6a8886p-17 (;=1.08043e-05;)
f32.add
f32.store offset=4
i32.const -1
return
end
local.get 1
local.get 0
f32.const 0x1.6a88p-17 (;=1.08043e-05;)
f32.add
local.tee 0
f32.const 0x1.0b461p-34 (;=6.0771e-11;)
f32.add
local.tee 2
f32.store
local.get 1
local.get 0
local.get 2
f32.sub
f32.const 0x1.0b461p-34 (;=6.0771e-11;)
f32.add
f32.store offset=4
i32.const -1
return
end
block ;; label = @1
block ;; label = @2
local.get 3
i32.const 1128861568
i32.gt_u
br_if 0 (;@2;)
block ;; label = @3
block ;; label = @4
local.get 2
f32.const 0x1.45f308p-1 (;=0.63662;)
f32.mul
f32.const 0x1p-1 (;=0.5;)
f32.add
local.tee 0
f32.abs
f32.const 0x1p+31 (;=2.14748e+09;)
f32.lt
i32.eqz
br_if 0 (;@4;)
local.get 0
i32.trunc_f32_s
local.set 5
br 1 (;@3;)
end
i32.const -2147483648
local.set 5
end
local.get 5
f32.convert_i32_s
local.tee 6
f32.const 0x1.6a8886p-17 (;=1.08043e-05;)
f32.mul
local.set 7
local.get 2
local.get 6
f32.const -0x1.921fp+0 (;=-1.57079;)
f32.mul
f32.add
local.set 0
block ;; label = @3
block ;; label = @4
block ;; label = @5
local.get 5
i32.const 31
i32.gt_s
br_if 0 (;@5;)
local.get 3
i32.const 2147483392
i32.and
local.get 5
i32.const 2
i32.shl
i32.const 1020
i32.add
i32.load
i32.ne
br_if 1 (;@4;)
end
local.get 1
local.get 0
local.get 7
f32.sub
local.tee 2
f32.store
local.get 3
i32.const 23
i32.shr_u
local.tee 3
local.get 2
i32.reinterpret_f32
i32.const 23
i32.shr_u
i32.const 255
i32.and
i32.sub
i32.const 9
i32.lt_s
br_if 1 (;@3;)
local.get 1
local.get 0
local.get 6
f32.const 0x1.6a88p-17 (;=1.08043e-05;)
f32.mul
local.tee 2
f32.sub
local.tee 8
local.get 6
f32.const 0x1.0b461p-34 (;=6.0771e-11;)
f32.mul
local.get 0
local.get 8
f32.sub
local.get 2
f32.sub
f32.sub
local.tee 7
f32.sub
local.tee 2
f32.store
block ;; label = @5
local.get 3
local.get 2
i32.reinterpret_f32
i32.const 23
i32.shr_u
i32.const 255
i32.and
i32.sub
i32.const 26
i32.ge_s
br_if 0 (;@5;)
local.get 8
local.set 0
br 2 (;@3;)
end
local.get 6
f32.const 0x1.1a6264p-54 (;=6.12323e-17;)
f32.mul
local.get 8
local.get 8
local.get 6
f32.const 0x1.0b46p-34 (;=6.07709e-11;)
f32.mul
local.tee 2
f32.sub
local.tee 0
f32.sub
local.get 2
f32.sub
f32.sub
local.set 7
end
local.get 1
local.get 0
local.get 7
f32.sub
local.tee 2
f32.store
end
local.get 1
local.get 0
local.get 2
f32.sub
local.get 7
f32.sub
local.tee 0
f32.store offset=4
local.get 4
i32.const -1
i32.gt_s
br_if 1 (;@1;)
local.get 1
local.get 0
f32.neg
f32.store offset=4
local.get 1
local.get 2
f32.neg
f32.store
i32.const 0
local.get 5
i32.sub
return
end
local.get 1
local.get 0
local.get 0
f32.sub
local.tee 0
f32.store
local.get 1
local.get 0
f32.store offset=4
i32.const 0
local.set 5
end
local.get 5)
(func $basicmath___cosf (type 4) (param f32) (result f32)
(local i32 i32 i32 i32 f32 f32 f32 f32)
global.get $__stack_pointer
i32.const 16
i32.sub
local.tee 1
global.set $__stack_pointer
block ;; label = @1
block ;; label = @2
local.get 0
i32.reinterpret_f32
i32.const 2147483647
i32.and
local.tee 2
i32.const 1061752792
i32.gt_u
br_if 0 (;@2;)
local.get 2
i32.const 838860799
i32.gt_u
local.set 3
block ;; label = @3
block ;; label = @4
local.get 0
f32.abs
f32.const 0x1p+31 (;=2.14748e+09;)
f32.lt
i32.eqz
br_if 0 (;@4;)
local.get 0
i32.trunc_f32_s
local.set 4
br 1 (;@3;)
end
i32.const -2147483648
local.set 4
end
block ;; label = @3
local.get 3
br_if 0 (;@3;)
local.get 4
br_if 0 (;@3;)
f32.const 0x1p+0 (;=1;)
local.set 0
br 2 (;@1;)
end
local.get 0
local.get 0
f32.mul
local.tee 5
local.get 5
local.get 5
local.get 5
local.get 5
local.get 5
f32.const -0x1.8fae9cp-37 (;=-1.13596e-11;)
f32.mul
f32.const 0x1.1ee9ecp-29 (;=2.08757e-09;)
f32.add
f32.mul
f32.const -0x1.27e4f8p-22 (;=-2.75573e-07;)
f32.add
f32.mul
f32.const 0x1.a01a02p-16 (;=2.48016e-05;)
f32.add
f32.mul
f32.const -0x1.6c16c2p-10 (;=-0.00138889;)
f32.add
f32.mul
f32.const 0x1.555556p-5 (;=0.0416667;)
f32.add
f32.mul
local.set 6
block ;; label = @3
local.get 2
i32.const 1050253721
i32.gt_u
br_if 0 (;@3;)
f32.const 0x1p+0 (;=1;)
local.get 5
f32.const 0x1p-1 (;=0.5;)
f32.mul
local.get 5
local.get 6
f32.mul
local.get 0
f32.const -0x0p+0 (;=-0;)
f32.mul
f32.add
f32.sub
f32.sub
local.set 0
br 2 (;@1;)
end
f32.const 0x1p+0 (;=1;)
f32.const 0x1.2p-2 (;=0.28125;)
local.get 2
i32.const -16777216
i32.add
f32.reinterpret_i32
local.get 2
i32.const 1061683200
i32.gt_u
select
local.tee 7
f32.sub
local.get 5
local.get 6
f32.mul
local.get 0
f32.const -0x0p+0 (;=-0;)
f32.mul
f32.add
local.get 5
f32.const 0x1p-1 (;=0.5;)
f32.mul
local.get 7
f32.sub
f32.sub
f32.add
local.set 0
br 1 (;@1;)
end
block ;; label = @2
local.get 2
i32.const 2139095040
i32.lt_u
br_if 0 (;@2;)
local.get 0
local.get 0
f32.sub
local.set 0
br 1 (;@1;)
end
local.get 0
local.get 1
i32.const 8
i32.add
call $basicmath___ieee754_rem_pio2f
local.set 2
local.get 1
f32.load offset=8
local.set 0
block ;; label = @2
block ;; label = @3
block ;; label = @4
block ;; label = @5
local.get 2
i32.const 3
i32.and
br_table 0 (;@5;) 1 (;@4;) 2 (;@3;) 3 (;@2;) 0 (;@5;)
end
local.get 0
i32.reinterpret_f32
i32.const 2147483647
i32.and
local.tee 2
i32.const 838860799
i32.gt_u
local.set 3
block ;; label = @5
block ;; label = @6
local.get 0
f32.abs
f32.const 0x1p+31 (;=2.14748e+09;)
f32.lt
i32.eqz
br_if 0 (;@6;)
local.get 0
i32.trunc_f32_s
local.set 4
br 1 (;@5;)
end
i32.const -2147483648
local.set 4
end
local.get 1
f32.load offset=12
local.set 6
block ;; label = @5
local.get 3
br_if 0 (;@5;)
local.get 4
br_if 0 (;@5;)
f32.const 0x1p+0 (;=1;)
local.set 0
br 4 (;@1;)
end
local.get 0
local.get 0
f32.mul
local.tee 5
local.get 5
local.get 5
local.get 5
local.get 5
local.get 5
f32.const -0x1.8fae9cp-37 (;=-1.13596e-11;)
f32.mul
f32.const 0x1.1ee9ecp-29 (;=2.08757e-09;)
f32.add
f32.mul
f32.const -0x1.27e4f8p-22 (;=-2.75573e-07;)
f32.add
f32.mul
f32.const 0x1.a01a02p-16 (;=2.48016e-05;)
f32.add
f32.mul
f32.const -0x1.6c16c2p-10 (;=-0.00138889;)
f32.add
f32.mul
f32.const 0x1.555556p-5 (;=0.0416667;)
f32.add
f32.mul
local.set 7
block ;; label = @5
local.get 2
i32.const 1050253721
i32.gt_u
br_if 0 (;@5;)
f32.const 0x1p+0 (;=1;)
local.get 5
f32.const 0x1p-1 (;=0.5;)
f32.mul
local.get 5
local.get 7
f32.mul
local.get 6
local.get 0
f32.mul
f32.sub
f32.sub
f32.sub
local.set 0
br 4 (;@1;)
end
f32.const 0x1p+0 (;=1;)
f32.const 0x1.2p-2 (;=0.28125;)
local.get 2
i32.const -16777216
i32.add
f32.reinterpret_i32
local.get 2
i32.const 1061683200
i32.gt_u
select
local.tee 8
f32.sub
local.get 5
local.get 7
f32.mul
local.get 6
local.get 0
f32.mul
f32.sub
local.get 5
f32.const 0x1p-1 (;=0.5;)
f32.mul
local.get 8
f32.sub
f32.sub
f32.add
local.set 0
br 3 (;@1;)
end
local.get 0
i32.reinterpret_f32
i32.const 2147483647
i32.and
i32.const 838860799
i32.gt_u
local.set 2
block ;; label = @4
block ;; label = @5
local.get 0
f32.abs
f32.const 0x1p+31 (;=2.14748e+09;)
f32.lt
i32.eqz
br_if 0 (;@5;)
local.get 0
i32.trunc_f32_s
local.set 3
br 1 (;@4;)
end
i32.const -2147483648
local.set 3
end
block ;; label = @4
block ;; label = @5
local.get 2
br_if 0 (;@5;)
local.get 3
i32.eqz
br_if 1 (;@4;)
end
local.get 0
local.get 0
local.get 0
local.get 0
f32.mul
local.tee 5
f32.neg
f32.mul
local.tee 6
f32.const -0x1.555556p-3 (;=-0.166667;)
f32.mul
local.get 5
local.get 1
f32.load offset=12
local.tee 7
f32.const 0x1p-1 (;=0.5;)
f32.mul
local.get 6
local.get 5
local.get 5
local.get 5
local.get 5
f32.const 0x1.5d93a6p-33 (;=1.58969e-10;)
f32.mul
f32.const -0x1.ae5e68p-26 (;=-2.50508e-08;)
f32.add
f32.mul
f32.const 0x1.71de36p-19 (;=2.75573e-06;)
f32.add
f32.mul
f32.const -0x1.a01a02p-13 (;=-0.000198413;)
f32.add
f32.mul
f32.const 0x1.111112p-7 (;=0.00833333;)
f32.add
f32.mul
f32.add
f32.mul
local.get 7
f32.sub
f32.add
f32.sub
local.set 0
end
local.get 0
f32.neg
local.set 0
br 2 (;@1;)
end
local.get 0
i32.reinterpret_f32
i32.const 2147483647
i32.and
local.tee 2
i32.const 838860799
i32.gt_u
local.set 3
block ;; label = @3
block ;; label = @4
local.get 0
f32.abs
f32.const 0x1p+31 (;=2.14748e+09;)
f32.lt
i32.eqz
br_if 0 (;@4;)
local.get 0
i32.trunc_f32_s
local.set 4
br 1 (;@3;)
end
i32.const -2147483648
local.set 4
end
local.get 1
f32.load offset=12
local.set 6
block ;; label = @3
block ;; label = @4
local.get 3
br_if 0 (;@4;)
f32.const 0x1p+0 (;=1;)
local.set 5
local.get 4
i32.eqz
br_if 1 (;@3;)
end
local.get 0
local.get 0
f32.mul
local.tee 5
local.get 5
local.get 5
local.get 5
local.get 5
local.get 5
f32.const -0x1.8fae9cp-37 (;=-1.13596e-11;)
f32.mul
f32.const 0x1.1ee9ecp-29 (;=2.08757e-09;)
f32.add
f32.mul
f32.const -0x1.27e4f8p-22 (;=-2.75573e-07;)
f32.add
f32.mul
f32.const 0x1.a01a02p-16 (;=2.48016e-05;)
f32.add
f32.mul
f32.const -0x1.6c16c2p-10 (;=-0.00138889;)
f32.add
f32.mul
f32.const 0x1.555556p-5 (;=0.0416667;)
f32.add
f32.mul
local.set 7
block ;; label = @4
local.get 2
i32.const 1050253721
i32.gt_u
br_if 0 (;@4;)
f32.const 0x1p+0 (;=1;)
local.get 5
f32.const 0x1p-1 (;=0.5;)
f32.mul
local.get 5
local.get 7
f32.mul
local.get 6
local.get 0
f32.mul
f32.sub
f32.sub
f32.sub
f32.neg
local.set 0
br 3 (;@1;)
end
f32.const 0x1p+0 (;=1;)
f32.const 0x1.2p-2 (;=0.28125;)
local.get 2
i32.const -16777216
i32.add
f32.reinterpret_i32
local.get 2
i32.const 1061683200
i32.gt_u
select
local.tee 8
f32.sub
local.get 5
local.get 7
f32.mul
local.get 6
local.get 0
f32.mul
f32.sub
local.get 5
f32.const 0x1p-1 (;=0.5;)
f32.mul
local.get 8
f32.sub
f32.sub
f32.add
local.set 5
end
local.get 5
f32.neg
local.set 0
br 1 (;@1;)
end
local.get 0
i32.reinterpret_f32
i32.const 2147483647
i32.and
i32.const 838860799
i32.gt_u
local.set 2
block ;; label = @2
block ;; label = @3
local.get 0
f32.abs
f32.const 0x1p+31 (;=2.14748e+09;)
f32.lt
i32.eqz
br_if 0 (;@3;)
local.get 0
i32.trunc_f32_s
local.set 3
br 1 (;@2;)
end
i32.const -2147483648
local.set 3
end
block ;; label = @2
local.get 2
br_if 0 (;@2;)
local.get 3
i32.eqz
br_if 1 (;@1;)
end
local.get 0
local.get 0
local.get 0
local.get 0
f32.mul
local.tee 5
f32.neg
f32.mul
local.tee 6
f32.const -0x1.555556p-3 (;=-0.166667;)
f32.mul
local.get 5
local.get 1
f32.load offset=12
local.tee 7
f32.const 0x1p-1 (;=0.5;)
f32.mul
local.get 6
local.get 5
local.get 5
local.get 5
local.get 5
f32.const 0x1.5d93a6p-33 (;=1.58969e-10;)
f32.mul
f32.const -0x1.ae5e68p-26 (;=-2.50508e-08;)
f32.add
f32.mul
f32.const 0x1.71de36p-19 (;=2.75573e-06;)
f32.add
f32.mul
f32.const -0x1.a01a02p-13 (;=-0.000198413;)
f32.add
f32.mul
f32.const 0x1.111112p-7 (;=0.00833333;)
f32.add
f32.mul
f32.add
f32.mul
local.get 7
f32.sub
f32.add
f32.sub
local.set 0
end
local.get 1
i32.const 16
i32.add
global.set $__stack_pointer
local.get 0)
(table (;0;) 1 1 funcref)
(memory (;0;) 1)
(global $__stack_pointer (mut i32) (i32.const 5264))
(global (;1;) i32 (i32.const 1156))
(global (;2;) i32 (i32.const 5264))
(export "memory" (memory 0))
(export "__wasm_apply_data_relocs" (func $__wasm_apply_data_relocs))
(export "entrypoint" (func $cosf_main))
(export "main" (func $__original_main))
(export "__data_end" (global 1))
(export "__heap_base" (global 2))
(data $.rodata (i32.const 1024) "\00\0f\c9?\00\0fI@\00\cb\96@\00\0f\c9@\00S\fb@\00\cb\16A\00\ed/A\00\0fIA\001bA\00S{A\00:\8aA\00\cb\96A\00\5c\a3A\00\ed\afA\00~\bcA\00\0f\c9A\00\a0\d5A\001\e2A\00\c2\eeA\00S\fbA\00\f2\03B\00:\0aB\00\83\10B\00\cb\16B\00\14\1dB\00\5c#B\00\a5)B\00\ed/B\0066B\00~<B\00\c7BB\00\0fIB"))

View File

@ -0,0 +1,85 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: cosf
Author: Dustin Green
Function: cosf performs calculations of the cosinus function
Source:
Original name:
Changes:
License: this code is FREE with no restrictions
*/
#include "wcclibm.h"
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
void cosf_init(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
cosf_main(void);
int cosf_return(void);
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
/*
Declaration of global variables
*/
float cosf_solutions;
/*
Initialization function
*/
void
cosf_init(void) {
cosf_solutions = 0.0f;
}
/*
Return function
*/
int
cosf_return(void) {
int temp = cosf_solutions;
if (temp == -4)
return 0;
else
return -1;
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
cosf_main(void) {
float i;
__pragma_loopbound(100, 100);
for (i = 0.0f; i < 10; i += 0.1f)
cosf_solutions += basicmath___cosf(i);
}
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
cosf_init();
cosf_main();
return cosf_return();
}

View File

@ -0,0 +1,67 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
from: @(#)fdlibm.h 5.1 93/09/24
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: math_private.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: fdlibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _MATH_PRIVATE_H_
#define _MATH_PRIVATE_H_
#include "wcclibm.h"
/* A union which permits us to convert between a float and a 32 bit int. */
typedef union {
float value;
u_int32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i, d) \
{ \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
}
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d, i) \
{ \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
}
#endif /* _MATH_PRIVATE_H_ */

View File

@ -0,0 +1,796 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.c
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.c
Changes: No major functional changes.
License: See the terms above.
*/
#include "wcclibm.h"
#include "math_private.h"
/* e_acosf.c -- float version of e_acos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
static const float basicmath_pi = 3.1415925026e+00f, /* 0x40490fda */
basicmath_pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */
basicmath_pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */
basicmath_pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_pS1 = -3.2556581497e-01f, /* 0xbea6b090 */
basicmath_pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */
basicmath_pS3 = -4.0055535734e-02f, /* 0xbd241146 */
basicmath_pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */
basicmath_pS5 = 3.4793309169e-05f, /* 0x3811ef08 */
basicmath_qS1 = -2.4033949375e+00f, /* 0xc019d139 */
basicmath_qS2 = 2.0209457874e+00f, /* 0x4001572d */
basicmath_qS3 = -6.8828397989e-01f, /* 0xbf303361 */
basicmath_qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */
float
basicmath___ieee754_acosf(float x) {
float z, p, q, r, w, s, c, df;
int32_t hx, ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix == 0x3f800000) { /* |x|==1 */
if (hx > 0)
return 0.0f; /* acos(1) = 0 */
else
return basicmath_pi +
(float) 2.0f * basicmath_pio2_lo; /* acos(-1)= pi */
} else if (ix > 0x3f800000) { /* |x| >= 1 */
return (x - x) / (x - x); /* acos(|x|>1) is NaN */
}
if (ix < 0x3f000000) { /* |x| < 0.5 */
if (ix <= 0x23000000)
return basicmath_pio2_hi + basicmath_pio2_lo; /*if|x|<2**-57*/
z = x * x;
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
r = p / q;
return basicmath_pio2_hi - (x - (basicmath_pio2_lo - x * r));
} else if (hx < 0) { /* x < -0.5 */
z = (basicmath_one + x) * (float) 0.5f;
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
s = basicmath___ieee754_sqrtf(z);
r = p / q;
w = r * s - basicmath_pio2_lo;
return basicmath_pi - (float) 2.0f * (s + w);
} else { /* x > 0.5 */
int32_t idf;
z = (basicmath_one - x) * (float) 0.5f;
s = basicmath___ieee754_sqrtf(z);
df = s;
GET_FLOAT_WORD(idf, df);
SET_FLOAT_WORD(df, idf & 0xfffff000);
c = (z - df * df) / (s + df);
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
r = p / q;
w = r * s + c;
return (float) 2.0f * (df + w);
}
}
/* e_powf.c -- float version of e_pow.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_bp[] =
{
1.0f,
1.5f,
},
basicmath_dp_h[] =
{
0.0f,
5.84960938e-01f,
}, /* 0x3f15c000 */
basicmath_dp_l[] =
{
0.0f,
1.56322085e-06f,
}, /* 0x35d1cfdc */
/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
basicmath_L1 = 6.0000002384e-01f, /* 0x3f19999a */
basicmath_L2 = 4.2857143283e-01f, /* 0x3edb6db7 */
basicmath_L3 = 3.3333334327e-01f, /* 0x3eaaaaab */
basicmath_L4 = 2.7272811532e-01f, /* 0x3e8ba305 */
basicmath_L5 = 2.3066075146e-01f, /* 0x3e6c3255 */
basicmath_L6 = 2.0697501302e-01f, /* 0x3e53f142 */
basicmath_P1 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_P2 = -2.7777778450e-03f, /* 0xbb360b61 */
basicmath_P3 = 6.6137559770e-05f, /* 0x388ab355 */
basicmath_P4 = -1.6533901999e-06f, /* 0xb5ddea0e */
basicmath_P5 = 4.1381369442e-08f, /* 0x3331bb4c */
basicmath_lg2 = 6.9314718246e-01f, /* 0x3f317218 */
basicmath_lg2_h = 6.93145752e-01f, /* 0x3f317200 */
basicmath_lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */
basicmath_ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */
basicmath_cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */
basicmath_cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */
basicmath_cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */
basicmath_ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */
basicmath_ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/
basicmath_ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/
float
basicmath___ieee754_powf(float x, float y) {
float z, ax, z_h, z_l, p_h, p_l;
float y1, t1, t2, r, s, t, u, v, w;
int32_t i, j, k, yisint, n;
int32_t hx, hy, ix, iy, is;
GET_FLOAT_WORD(hx, x);
GET_FLOAT_WORD(hy, y);
ix = hx & 0x7fffffff;
iy = hy & 0x7fffffff;
/* y==zero: x**0 = 1 */
if (iy == 0)
return basicmath_one;
/* x==+-1 */
if (x == 1.0f)
return basicmath_one;
if (x == -1.0f && basicmath___isinff(y))
return basicmath_one;
/* +-NaN return x+y */
if (ix > 0x7f800000 || iy > 0x7f800000)
return x + y;
/* determine if y is an odd int when x < 0
yisint = 0 ... y is not an integer
yisint = 1 ... y is an odd int
yisint = 2 ... y is an even int
*/
yisint = 0;
if (hx < 0) {
if (iy >= 0x4b800000)
yisint = 2; /* even integer y */
else if (iy >= 0x3f800000) {
k = (iy >> 23) - 0x7f; /* exponent */
j = iy >> (23 - k);
if ((j << (23 - k)) == iy)
yisint = 2 - (j & 1);
}
}
/* special value of y */
if (iy == 0x7f800000) { /* y is +-inf */
if (ix == 0x3f800000)
return y - y; /* inf**+-1 is NaN */
else if (ix > 0x3f800000) /* (|x|>1)**+-inf = inf,0 */
return (hy >= 0) ? y : basicmath_zero;
else /* (|x|<1)**-,+inf = inf,0 */
return (hy < 0) ? -y : basicmath_zero;
}
if (iy == 0x3f800000) { /* y is +-1 */
if (hy < 0)
return basicmath_one / x;
else
return x;
}
if (hy == 0x40000000)
return x * x; /* y is 2 */
if (hy == 0x3f000000) { /* y is 0.5 */
if (hx >= 0) /* x >= +0 */
return basicmath___ieee754_sqrtf(x);
}
ax = basicmath___fabsf(x);
/* special value of x */
if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) {
z = ax; /*x is +-0,+-inf,+-1*/
if (hy < 0)
z = basicmath_one / z; /* z = (1/|x|) */
if (hx < 0) {
if (((ix - 0x3f800000) | yisint) == 0) {
z = (z - z) / (z - z); /* (-1)**non-int is NaN */
} else if (yisint == 1)
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
/* (x<0)**(non-int) is NaN */
if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0)
return (x - x) / (x - x);
/* |y| is huge */
if (iy > 0x4d000000) { /* if |y| > 2**27 */
/* over/underflow if x is not close to one */
if (ix < 0x3f7ffff8)
return (hy < 0) ? basicmath_huge * basicmath_huge
: basicmath_tiny * basicmath_tiny;
if (ix > 0x3f800007)
return (hy > 0) ? basicmath_huge * basicmath_huge
: basicmath_tiny * basicmath_tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = x - 1; /* t has 20 trailing zeros */
w = (t * t) *
((float) 0.5f - t * ((float) 0.333333333333f - t * (float) 0.25f));
u = basicmath_ivln2_h * t; /* ivln2_h has 16 sig. bits */
v = t * basicmath_ivln2_l - w * basicmath_ivln2;
t1 = u + v;
GET_FLOAT_WORD(is, t1);
SET_FLOAT_WORD(t1, is & 0xfffff000);
t2 = v - (t1 - u);
} else {
float s2, s_h, s_l, t_h, t_l;
n = 0;
/* take care subnormal number */
if (ix < 0x00800000) {
ax *= basicmath_two24;
n -= 24;
GET_FLOAT_WORD(ix, ax);
}
n += ((ix) >> 23) - 0x7f;
j = ix & 0x007fffff;
/* determine interval */
ix = j | 0x3f800000; /* normalize ix */
if (j <= 0x1cc471)
k = 0; /* |x|<sqrt(3/2) */
else if (j < 0x5db3d7)
k = 1; /* |x|<sqrt(3) */
else {
k = 0;
n += 1;
ix -= 0x00800000;
}
SET_FLOAT_WORD(ax, ix);
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
u = ax - basicmath_bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
v = basicmath_one / (ax + basicmath_bp[k]);
s = u * v;
s_h = s;
GET_FLOAT_WORD(is, s_h);
SET_FLOAT_WORD(s_h, is & 0xfffff000);
/* t_h=ax+bp[k] High */
SET_FLOAT_WORD(t_h, ((ix >> 1) | 0x20000000) + 0x0040000 + (k << 21));
t_l = ax - (t_h - basicmath_bp[k]);
s_l = v * ((u - s_h * t_h) - s_h * t_l);
/* compute log(ax) */
s2 = s * s;
r = s2 * s2 *
(basicmath_L1 +
s2 * (basicmath_L2 +
s2 * (basicmath_L3 +
s2 * (basicmath_L4 +
s2 * (basicmath_L5 + s2 * basicmath_L6)))));
r += s_l * (s_h + s);
s2 = s_h * s_h;
t_h = (float) 3.0f + s2 + r;
GET_FLOAT_WORD(is, t_h);
SET_FLOAT_WORD(t_h, is & 0xfffff000);
t_l = r - ((t_h - (float) 3.0f) - s2);
/* u+v = s*(1+...) */
u = s_h * t_h;
v = s_l * t_h + t_l * s;
/* 2/(3log2)*(s+...) */
p_h = u + v;
GET_FLOAT_WORD(is, p_h);
SET_FLOAT_WORD(p_h, is & 0xfffff000);
p_l = v - (p_h - u);
z_h = basicmath_cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = basicmath_cp_l * p_h + p_l * basicmath_cp + basicmath_dp_l[k];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = (float) n;
t1 = (((z_h + z_l) + basicmath_dp_h[k]) + t);
GET_FLOAT_WORD(is, t1);
SET_FLOAT_WORD(t1, is & 0xfffff000);
t2 = z_l - (((t1 - t) - basicmath_dp_h[k]) - z_h);
}
s = basicmath_one; /* s (sign of result -ve**odd) = -1 else = 1 */
if (((((u_int32_t) hx >> 31) - 1) | (yisint - 1)) == 0)
s = -basicmath_one; /* (-ve)**(odd int) */
/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
GET_FLOAT_WORD(is, y);
SET_FLOAT_WORD(y1, is & 0xfffff000);
p_l = (y - y1) * t1 + y * t2;
p_h = y1 * t1;
z = p_l + p_h;
GET_FLOAT_WORD(j, z);
if (j > 0x43000000) /* if z > 128 */
return s * basicmath_huge * basicmath_huge; /* overflow */
else if (j == 0x43000000) { /* if z == 128 */
if (p_l + basicmath_ovt > z - p_h)
return s * basicmath_huge * basicmath_huge; /* overflow */
} else if ((j & 0x7fffffff) > 0x43160000) /* z <= -150 */
return s * basicmath_tiny * basicmath_tiny; /* underflow */
else if ((u_int32_t) j == 0xc3160000) { /* z == -150 */
if (p_l <= z - p_h)
return s * basicmath_tiny * basicmath_tiny; /* underflow */
}
/*
compute 2**(p_h+p_l)
*/
i = j & 0x7fffffff;
k = (i >> 23) - 0x7f;
n = 0;
if (i > 0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
n = j + (0x00800000 >> (k + 1));
k = ((n & 0x7fffffff) >> 23) - 0x7f; /* new k for n */
SET_FLOAT_WORD(t, n & ~(0x007fffff >> k));
n = ((n & 0x007fffff) | 0x00800000) >> (23 - k);
if (j < 0)
n = -n;
p_h -= t;
}
t = p_l + p_h;
GET_FLOAT_WORD(is, t);
SET_FLOAT_WORD(t, is & 0xfffff000);
u = t * basicmath_lg2_h;
v = (p_l - (t - p_h)) * basicmath_lg2 + t * basicmath_lg2_l;
z = u + v;
w = v - (z - u);
t = z * z;
t1 = z -
t * (basicmath_P1 +
t * (basicmath_P2 +
t * (basicmath_P3 + t * (basicmath_P4 + t * basicmath_P5))));
r = (z * t1) / (t1 - basicmath_two) - (w + z * w);
z = basicmath_one - (r - z);
GET_FLOAT_WORD(j, z);
j += (n << 23);
if ((j >> 23) <= 0)
z = basicmath___scalbnf(z, n); /* subnormal output */
else
SET_FLOAT_WORD(z, j);
return s * z;
}
/* e_rem_pio2f.c -- float version of e_rem_pio2.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/* basicmath___ieee754_rem_pio2f(x,y)
return the remainder of x rem pi/2 in y[0]+y[1]
*/
/* This array is like the one in e_rem_pio2.c, but the numbers are
single precision and the last 8 bits are forced to 0. */
static const int32_t basicmath_npio2_hw[] = {
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
0x4242c700, 0x42490f00};
/*
invpio2: 24 bits of 2/pi
pio2_1: first 17 bit of pi/2
pio2_1t: pi/2 - pio2_1
pio2_2: second 17 bit of pi/2
pio2_2t: pi/2 - (pio2_1+pio2_2)
pio2_3: third 17 bit of pi/2
pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const float basicmath_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
basicmath_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
basicmath_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
basicmath_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
basicmath_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
basicmath_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
basicmath_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
int32_t
basicmath___ieee754_rem_pio2f(float x, float *y) {
float z, w, t, r, fn;
int32_t i, j, n, ix, hx;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix <= 0x3f490fd8) { /* |x| ~<= pi/4 , no need for reduction */
y[0] = x;
y[1] = 0;
return 0;
}
if (ix < 0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
if (hx > 0) {
z = x - basicmath_pio2_1;
if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */
y[0] = z - basicmath_pio2_1t;
y[1] = (z - y[0]) - basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z -= basicmath_pio2_2;
y[0] = z - basicmath_pio2_2t;
y[1] = (z - y[0]) - basicmath_pio2_2t;
}
return 1;
} else { /* negative x */
z = x + basicmath_pio2_1;
if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */
y[0] = z + basicmath_pio2_1t;
y[1] = (z - y[0]) + basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z += basicmath_pio2_2;
y[0] = z + basicmath_pio2_2t;
y[1] = (z - y[0]) + basicmath_pio2_2t;
}
return -1;
}
}
if (ix <= 0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
t = basicmath___fabsf(x);
n = (int32_t) (t * basicmath_invpio2 + basicmath_half);
fn = (float) n;
r = t - fn * basicmath_pio2_1;
w = fn * basicmath_pio2_1t; /* 1st round good to 40 bit */
if (n < 32 &&
(int32_t) (ix & 0xffffff00) != basicmath_npio2_hw[n - 1]) {
y[0] = r - w; /* quick check no cancellation */
} else {
u_int32_t high;
j = ix >> 23;
y[0] = r - w;
GET_FLOAT_WORD(high, y[0]);
i = j - ((high >> 23) & 0xff);
if (i > 8) { /* 2nd iteration needed, good to 57 */
t = r;
w = fn * basicmath_pio2_2;
r = t - w;
w = fn * basicmath_pio2_2t - ((t - r) - w);
y[0] = r - w;
GET_FLOAT_WORD(high, y[0]);
i = j - ((high >> 23) & 0xff);
if (i > 25) { /* 3rd iteration need, 74 bits acc */
t = r; /* will cover all possible cases */
w = fn * basicmath_pio2_3;
r = t - w;
w = fn * basicmath_pio2_3t - ((t - r) - w);
y[0] = r - w;
}
}
}
y[1] = (r - y[0]) - w;
if (hx < 0) {
y[0] = -y[0];
y[1] = -y[1];
return -n;
} else
return n;
}
/*
all other (large) arguments
*/
if (ix >= 0x7f800000) { /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
// This will never happen in basicmath_small, because
// up to this point we have already returned a value
// for each of the possible inputs
y[0] = y[1] = x - x; /* dummy initialization */
return 0;
}
/* e_sqrtf.c -- float version of e_sqrt.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
float
basicmath___ieee754_sqrtf(float x) {
float z;
int32_t sign = (int) 0x80000000;
int32_t ix, s, q, m, t, i;
u_int32_t r;
GET_FLOAT_WORD(ix, x);
/* take care of Inf and NaN */
if ((ix & 0x7f800000) == 0x7f800000) {
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if (ix <= 0) {
if ((ix & (~sign)) == 0)
return x; /* sqrt(+-0) = +-0 */
else if (ix < 0)
return (x - x) / (x - x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix >> 23);
if (m == 0) { /* subnormal x */
__pragma_loopbound(0, 0);
for (i = 0; (ix & 0x00800000) == 0; i++)
ix <<= 1;
m -= i - 1;
}
m -= 127; /* unbias exponent */
ix = (ix & 0x007fffff) | 0x00800000;
if (m & 1) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
__pragma_loopbound(25, 25);
while (r != 0) {
t = s + r;
if (t <= ix) {
s = t + r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
/* use floating add to find out rounding direction */
if (ix != 0) {
z = basicmath_one - basicmath_tiny; /* trigger inexact flag */
if (z >= basicmath_one) {
z = basicmath_one + basicmath_tiny;
if (z > basicmath_one)
q += 2;
else
q += (q & 1);
}
}
ix = (q >> 1) + 0x3f000000;
ix += (m << 23);
SET_FLOAT_WORD(z, ix);
return z;
}
/* k_cosf.c -- float version of k_cos.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
basicmath_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
basicmath_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
basicmath_C4 = -2.7557314297e-07f, /* 0xb493f27c */
basicmath_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
basicmath_C6 = -1.1359647598e-11f; /* 0xad47d74e */
float
basicmath___kernel_cosf(float x, float y) {
float a, hz, z, r, qx;
int32_t ix;
GET_FLOAT_WORD(ix, x);
ix &= 0x7fffffff; /* ix = |x|'s high word*/
if (ix < 0x32000000) { /* if x < 2**27 */
if (((int) x) == 0)
return basicmath_one; /* generate inexact */
}
z = x * x;
r = z * (basicmath_C1 +
z * (basicmath_C2 +
z * (basicmath_C3 +
z * (basicmath_C4 +
z * (basicmath_C5 + z * basicmath_C6)))));
if (ix < 0x3e99999a) /* if |x| < 0.3 */
return basicmath_one - ((float) 0.5f * z - (z * r - x * y));
else {
if (ix > 0x3f480000) /* x > 0.78125 */
qx = (float) 0.28125f;
else {
SET_FLOAT_WORD(qx, ix - 0x01000000); /* x/4 */
}
hz = (float) 0.5f * z - qx;
a = basicmath_one - qx;
return a - (hz - (z * r - x * y));
}
}
/* k_sinf.c -- float version of k_sin.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
basicmath_S2 = 8.3333337680e-03f, /* 0x3c088889 */
basicmath_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
basicmath_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
basicmath_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
basicmath_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
float
basicmath___kernel_sinf(float x, float y, int iy) {
float z, r, v;
int32_t ix;
GET_FLOAT_WORD(ix, x);
ix &= 0x7fffffff; /* high word of x */
if (ix < 0x32000000) { /* |x| < 2**-27 */
if ((int) x == 0)
return x; /* generate inexact */
}
z = x * x;
v = z * x;
r = basicmath_S2 +
z * (basicmath_S3 +
z * (basicmath_S4 + z * (basicmath_S5 + z * basicmath_S6)));
if (iy == 0)
return x + v * (basicmath_S1 + z * r);
else
return x - ((z * (basicmath_half * y - v * r) - y) - v * basicmath_S1);
}
/* s_copysignf.c -- float version of s_copysign.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
copysignf(float x, float y)
copysignf(x,y) returns a value with the magnitude of x and
with the sign bit of y.
*/
float
basicmath___copysignf(float x, float y) {
u_int32_t ix, iy;
GET_FLOAT_WORD(ix, x);
GET_FLOAT_WORD(iy, y);
SET_FLOAT_WORD(x, (ix & 0x7fffffff) | (iy & 0x80000000));
return x;
}
/* s_cosf.c -- float version of s_cos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
float
basicmath___cosf(float x) {
float y[2], z = 0.0f;
int32_t n, ix;
GET_FLOAT_WORD(ix, x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if (ix <= 0x3f490fd8)
return basicmath___kernel_cosf(x, z);
/* cos(Inf or NaN) is NaN */
else if (ix >= 0x7f800000)
return x - x;
/* argument reduction needed */
else {
n = basicmath___ieee754_rem_pio2f(x, y);
switch (n & 3) {
case 0:
return basicmath___kernel_cosf(y[0], y[1]);
case 1:
return -basicmath___kernel_sinf(y[0], y[1], 1);
case 2:
return -basicmath___kernel_cosf(y[0], y[1]);
default:
return basicmath___kernel_sinf(y[0], y[1], 1);
}
}
}
/* s_fabsf.c -- float version of s_fabs.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
fabsf(x) returns the absolute value of x.
*/
float
basicmath___fabsf(float x) {
u_int32_t ix;
GET_FLOAT_WORD(ix, x);
SET_FLOAT_WORD(x, ix & 0x7fffffff);
return x;
}
/*
isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
no branching!
*/
int
basicmath___isinff(float x) {
int32_t ix, t;
GET_FLOAT_WORD(ix, x);
t = ix & 0x7fffffff;
t ^= 0x7f800000;
t |= -t;
return ~(t >> 31) & (ix >> 30);
}
/* s_scalbnf.c -- float version of s_scalbn.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_two25 = 3.355443200e+07f, /* 0x4c000000 */
basicmath_twom25 = 2.9802322388e-08f; /* 0x33000000 */
float
basicmath___scalbnf(float x, int n) {
int32_t k, ix;
GET_FLOAT_WORD(ix, x);
k = (ix & 0x7f800000) >> 23; /* extract exponent */
if (k == 0) { /* 0 or subnormal x */
if ((ix & 0x7fffffff) == 0)
return x; /* +-0 */
x *= basicmath_two25;
GET_FLOAT_WORD(ix, x);
k = ((ix & 0x7f800000) >> 23) - 25;
}
if (k == 0xff)
return x + x; /* NaN or Inf */
k = k + n;
if (n > 50000 || k > 0xfe)
return basicmath_huge *
basicmath___copysignf(basicmath_huge, x); /* overflow */
if (n < -50000)
return basicmath_tiny *
basicmath___copysignf(basicmath_tiny, x); /*underflow*/
if (k > 0) { /* normal result */
SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
return x;
}
if (k <= -25)
return basicmath_tiny *
basicmath___copysignf(basicmath_tiny, x); /*underflow*/
k += 25; /* subnormal result */
SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
return x * basicmath_twom25;
}

View File

@ -0,0 +1,58 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _WCCLIBM
#define _WCCLIBM
#define int32_t int
#define u_int32_t unsigned int
// Often used variables/consts
static const float basicmath_one = 1.0f, basicmath_tiny = 1.0e-30f,
basicmath_half = 5.0000000000e-01, /* 0x3f000000 */
basicmath_huge = 1.0e30, basicmath_two = 2.0,
basicmath_two24 = 16777216.0, /* 0x4b800000 */
basicmath_zero = 0.0;
float basicmath___copysignf(float x, float y);
float basicmath___cosf(float x);
float basicmath___fabsf(float x);
float basicmath___ieee754_acosf(float x);
float basicmath___ieee754_powf(float x, float y);
int32_t basicmath___ieee754_rem_pio2f(float x, float *y);
float basicmath___ieee754_sqrtf(float x);
int basicmath___isinff(float x);
float basicmath___kernel_cosf(float x, float y);
float basicmath___kernel_sinf(float x, float y, int iy);
float basicmath___scalbnf(float x, int n);
#endif // _WCCLIBM

View File

@ -0,0 +1,94 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: cosf
Author: Dustin Green
Function: cosf performs calculations of the cosinus function
Source:
Original name:
Changes:
License: this code is FREE with no restrictions
*/
#include "wcclibm.h"
/*
Forward declaration of functions
*/
// Wasm loop bounds
#include "wcclibm.c"
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
__attribute__((always_inline)) static inline void cosf_init(void);
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
cosf_main(void);
__attribute__((always_inline)) static inline int cosf_return(void);
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void);
/*
Declaration of global variables
*/
float cosf_solutions;
/*
Initialization function
*/
__attribute__((always_inline)) static inline void
cosf_init(void) {
cosf_solutions = 0.0f;
}
/*
Return function
*/
__attribute__((always_inline)) static inline int
cosf_return(void) {
int temp = cosf_solutions;
if (temp == -4)
return 0;
else
return -1;
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
cosf_main(void) {
float i;
__pragma_loopbound(100, 100);
for (i = 0.0f; i < 10; i += 0.1f)
cosf_solutions += basicmath___cosf(i);
}
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
cosf_init();
cosf_main();
return cosf_return();
}

View File

@ -0,0 +1,67 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
from: @(#)fdlibm.h 5.1 93/09/24
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: math_private.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: fdlibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _MATH_PRIVATE_H_
#define _MATH_PRIVATE_H_
#include "wcclibm.h"
/* A union which permits us to convert between a float and a 32 bit int. */
typedef union {
float value;
u_int32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i, d) \
{ \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
}
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d, i) \
{ \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
}
#endif /* _MATH_PRIVATE_H_ */

View File

@ -0,0 +1,796 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.c
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.c
Changes: No major functional changes.
License: See the terms above.
*/
#include "wcclibm.h"
#include "math_private.h"
/* e_acosf.c -- float version of e_acos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
static const float basicmath_pi = 3.1415925026e+00f, /* 0x40490fda */
basicmath_pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */
basicmath_pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */
basicmath_pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_pS1 = -3.2556581497e-01f, /* 0xbea6b090 */
basicmath_pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */
basicmath_pS3 = -4.0055535734e-02f, /* 0xbd241146 */
basicmath_pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */
basicmath_pS5 = 3.4793309169e-05f, /* 0x3811ef08 */
basicmath_qS1 = -2.4033949375e+00f, /* 0xc019d139 */
basicmath_qS2 = 2.0209457874e+00f, /* 0x4001572d */
basicmath_qS3 = -6.8828397989e-01f, /* 0xbf303361 */
basicmath_qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */
__attribute__((always_inline)) static inline float
basicmath___ieee754_acosf(float x) {
float z, p, q, r, w, s, c, df;
int32_t hx, ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix == 0x3f800000) { /* |x|==1 */
if (hx > 0)
return 0.0f; /* acos(1) = 0 */
else
return basicmath_pi +
(float) 2.0f * basicmath_pio2_lo; /* acos(-1)= pi */
} else if (ix > 0x3f800000) { /* |x| >= 1 */
return (x - x) / (x - x); /* acos(|x|>1) is NaN */
}
if (ix < 0x3f000000) { /* |x| < 0.5 */
if (ix <= 0x23000000)
return basicmath_pio2_hi + basicmath_pio2_lo; /*if|x|<2**-57*/
z = x * x;
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
r = p / q;
return basicmath_pio2_hi - (x - (basicmath_pio2_lo - x * r));
} else if (hx < 0) { /* x < -0.5 */
z = (basicmath_one + x) * (float) 0.5f;
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
s = basicmath___ieee754_sqrtf(z);
r = p / q;
w = r * s - basicmath_pio2_lo;
return basicmath_pi - (float) 2.0f * (s + w);
} else { /* x > 0.5 */
int32_t idf;
z = (basicmath_one - x) * (float) 0.5f;
s = basicmath___ieee754_sqrtf(z);
df = s;
GET_FLOAT_WORD(idf, df);
SET_FLOAT_WORD(df, idf & 0xfffff000);
c = (z - df * df) / (s + df);
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
r = p / q;
w = r * s + c;
return (float) 2.0f * (df + w);
}
}
/* e_powf.c -- float version of e_pow.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_bp[] =
{
1.0f,
1.5f,
},
basicmath_dp_h[] =
{
0.0f,
5.84960938e-01f,
}, /* 0x3f15c000 */
basicmath_dp_l[] =
{
0.0f,
1.56322085e-06f,
}, /* 0x35d1cfdc */
/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
basicmath_L1 = 6.0000002384e-01f, /* 0x3f19999a */
basicmath_L2 = 4.2857143283e-01f, /* 0x3edb6db7 */
basicmath_L3 = 3.3333334327e-01f, /* 0x3eaaaaab */
basicmath_L4 = 2.7272811532e-01f, /* 0x3e8ba305 */
basicmath_L5 = 2.3066075146e-01f, /* 0x3e6c3255 */
basicmath_L6 = 2.0697501302e-01f, /* 0x3e53f142 */
basicmath_P1 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_P2 = -2.7777778450e-03f, /* 0xbb360b61 */
basicmath_P3 = 6.6137559770e-05f, /* 0x388ab355 */
basicmath_P4 = -1.6533901999e-06f, /* 0xb5ddea0e */
basicmath_P5 = 4.1381369442e-08f, /* 0x3331bb4c */
basicmath_lg2 = 6.9314718246e-01f, /* 0x3f317218 */
basicmath_lg2_h = 6.93145752e-01f, /* 0x3f317200 */
basicmath_lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */
basicmath_ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */
basicmath_cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */
basicmath_cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */
basicmath_cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */
basicmath_ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */
basicmath_ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/
basicmath_ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/
__attribute__((always_inline)) static inline float
basicmath___ieee754_powf(float x, float y) {
float z, ax, z_h, z_l, p_h, p_l;
float y1, t1, t2, r, s, t, u, v, w;
int32_t i, j, k, yisint, n;
int32_t hx, hy, ix, iy, is;
GET_FLOAT_WORD(hx, x);
GET_FLOAT_WORD(hy, y);
ix = hx & 0x7fffffff;
iy = hy & 0x7fffffff;
/* y==zero: x**0 = 1 */
if (iy == 0)
return basicmath_one;
/* x==+-1 */
if (x == 1.0f)
return basicmath_one;
if (x == -1.0f && basicmath___isinff(y))
return basicmath_one;
/* +-NaN return x+y */
if (ix > 0x7f800000 || iy > 0x7f800000)
return x + y;
/* determine if y is an odd int when x < 0
yisint = 0 ... y is not an integer
yisint = 1 ... y is an odd int
yisint = 2 ... y is an even int
*/
yisint = 0;
if (hx < 0) {
if (iy >= 0x4b800000)
yisint = 2; /* even integer y */
else if (iy >= 0x3f800000) {
k = (iy >> 23) - 0x7f; /* exponent */
j = iy >> (23 - k);
if ((j << (23 - k)) == iy)
yisint = 2 - (j & 1);
}
}
/* special value of y */
if (iy == 0x7f800000) { /* y is +-inf */
if (ix == 0x3f800000)
return y - y; /* inf**+-1 is NaN */
else if (ix > 0x3f800000) /* (|x|>1)**+-inf = inf,0 */
return (hy >= 0) ? y : basicmath_zero;
else /* (|x|<1)**-,+inf = inf,0 */
return (hy < 0) ? -y : basicmath_zero;
}
if (iy == 0x3f800000) { /* y is +-1 */
if (hy < 0)
return basicmath_one / x;
else
return x;
}
if (hy == 0x40000000)
return x * x; /* y is 2 */
if (hy == 0x3f000000) { /* y is 0.5 */
if (hx >= 0) /* x >= +0 */
return basicmath___ieee754_sqrtf(x);
}
ax = basicmath___fabsf(x);
/* special value of x */
if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) {
z = ax; /*x is +-0,+-inf,+-1*/
if (hy < 0)
z = basicmath_one / z; /* z = (1/|x|) */
if (hx < 0) {
if (((ix - 0x3f800000) | yisint) == 0) {
z = (z - z) / (z - z); /* (-1)**non-int is NaN */
} else if (yisint == 1)
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
/* (x<0)**(non-int) is NaN */
if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0)
return (x - x) / (x - x);
/* |y| is huge */
if (iy > 0x4d000000) { /* if |y| > 2**27 */
/* over/underflow if x is not close to one */
if (ix < 0x3f7ffff8)
return (hy < 0) ? basicmath_huge * basicmath_huge
: basicmath_tiny * basicmath_tiny;
if (ix > 0x3f800007)
return (hy > 0) ? basicmath_huge * basicmath_huge
: basicmath_tiny * basicmath_tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = x - 1; /* t has 20 trailing zeros */
w = (t * t) *
((float) 0.5f - t * ((float) 0.333333333333f - t * (float) 0.25f));
u = basicmath_ivln2_h * t; /* ivln2_h has 16 sig. bits */
v = t * basicmath_ivln2_l - w * basicmath_ivln2;
t1 = u + v;
GET_FLOAT_WORD(is, t1);
SET_FLOAT_WORD(t1, is & 0xfffff000);
t2 = v - (t1 - u);
} else {
float s2, s_h, s_l, t_h, t_l;
n = 0;
/* take care subnormal number */
if (ix < 0x00800000) {
ax *= basicmath_two24;
n -= 24;
GET_FLOAT_WORD(ix, ax);
}
n += ((ix) >> 23) - 0x7f;
j = ix & 0x007fffff;
/* determine interval */
ix = j | 0x3f800000; /* normalize ix */
if (j <= 0x1cc471)
k = 0; /* |x|<sqrt(3/2) */
else if (j < 0x5db3d7)
k = 1; /* |x|<sqrt(3) */
else {
k = 0;
n += 1;
ix -= 0x00800000;
}
SET_FLOAT_WORD(ax, ix);
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
u = ax - basicmath_bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
v = basicmath_one / (ax + basicmath_bp[k]);
s = u * v;
s_h = s;
GET_FLOAT_WORD(is, s_h);
SET_FLOAT_WORD(s_h, is & 0xfffff000);
/* t_h=ax+bp[k] High */
SET_FLOAT_WORD(t_h, ((ix >> 1) | 0x20000000) + 0x0040000 + (k << 21));
t_l = ax - (t_h - basicmath_bp[k]);
s_l = v * ((u - s_h * t_h) - s_h * t_l);
/* compute log(ax) */
s2 = s * s;
r = s2 * s2 *
(basicmath_L1 +
s2 * (basicmath_L2 +
s2 * (basicmath_L3 +
s2 * (basicmath_L4 +
s2 * (basicmath_L5 + s2 * basicmath_L6)))));
r += s_l * (s_h + s);
s2 = s_h * s_h;
t_h = (float) 3.0f + s2 + r;
GET_FLOAT_WORD(is, t_h);
SET_FLOAT_WORD(t_h, is & 0xfffff000);
t_l = r - ((t_h - (float) 3.0f) - s2);
/* u+v = s*(1+...) */
u = s_h * t_h;
v = s_l * t_h + t_l * s;
/* 2/(3log2)*(s+...) */
p_h = u + v;
GET_FLOAT_WORD(is, p_h);
SET_FLOAT_WORD(p_h, is & 0xfffff000);
p_l = v - (p_h - u);
z_h = basicmath_cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = basicmath_cp_l * p_h + p_l * basicmath_cp + basicmath_dp_l[k];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = (float) n;
t1 = (((z_h + z_l) + basicmath_dp_h[k]) + t);
GET_FLOAT_WORD(is, t1);
SET_FLOAT_WORD(t1, is & 0xfffff000);
t2 = z_l - (((t1 - t) - basicmath_dp_h[k]) - z_h);
}
s = basicmath_one; /* s (sign of result -ve**odd) = -1 else = 1 */
if (((((u_int32_t) hx >> 31) - 1) | (yisint - 1)) == 0)
s = -basicmath_one; /* (-ve)**(odd int) */
/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
GET_FLOAT_WORD(is, y);
SET_FLOAT_WORD(y1, is & 0xfffff000);
p_l = (y - y1) * t1 + y * t2;
p_h = y1 * t1;
z = p_l + p_h;
GET_FLOAT_WORD(j, z);
if (j > 0x43000000) /* if z > 128 */
return s * basicmath_huge * basicmath_huge; /* overflow */
else if (j == 0x43000000) { /* if z == 128 */
if (p_l + basicmath_ovt > z - p_h)
return s * basicmath_huge * basicmath_huge; /* overflow */
} else if ((j & 0x7fffffff) > 0x43160000) /* z <= -150 */
return s * basicmath_tiny * basicmath_tiny; /* underflow */
else if ((u_int32_t) j == 0xc3160000) { /* z == -150 */
if (p_l <= z - p_h)
return s * basicmath_tiny * basicmath_tiny; /* underflow */
}
/*
compute 2**(p_h+p_l)
*/
i = j & 0x7fffffff;
k = (i >> 23) - 0x7f;
n = 0;
if (i > 0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
n = j + (0x00800000 >> (k + 1));
k = ((n & 0x7fffffff) >> 23) - 0x7f; /* new k for n */
SET_FLOAT_WORD(t, n & ~(0x007fffff >> k));
n = ((n & 0x007fffff) | 0x00800000) >> (23 - k);
if (j < 0)
n = -n;
p_h -= t;
}
t = p_l + p_h;
GET_FLOAT_WORD(is, t);
SET_FLOAT_WORD(t, is & 0xfffff000);
u = t * basicmath_lg2_h;
v = (p_l - (t - p_h)) * basicmath_lg2 + t * basicmath_lg2_l;
z = u + v;
w = v - (z - u);
t = z * z;
t1 = z -
t * (basicmath_P1 +
t * (basicmath_P2 +
t * (basicmath_P3 + t * (basicmath_P4 + t * basicmath_P5))));
r = (z * t1) / (t1 - basicmath_two) - (w + z * w);
z = basicmath_one - (r - z);
GET_FLOAT_WORD(j, z);
j += (n << 23);
if ((j >> 23) <= 0)
z = basicmath___scalbnf(z, n); /* subnormal output */
else
SET_FLOAT_WORD(z, j);
return s * z;
}
/* e_rem_pio2f.c -- float version of e_rem_pio2.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/* basicmath___ieee754_rem_pio2f(x,y)
return the remainder of x rem pi/2 in y[0]+y[1]
*/
/* This array is like the one in e_rem_pio2.c, but the numbers are
single precision and the last 8 bits are forced to 0. */
static const int32_t basicmath_npio2_hw[] = {
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
0x4242c700, 0x42490f00};
/*
invpio2: 24 bits of 2/pi
pio2_1: first 17 bit of pi/2
pio2_1t: pi/2 - pio2_1
pio2_2: second 17 bit of pi/2
pio2_2t: pi/2 - (pio2_1+pio2_2)
pio2_3: third 17 bit of pi/2
pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const float basicmath_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
basicmath_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
basicmath_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
basicmath_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
basicmath_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
basicmath_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
basicmath_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
__attribute__((always_inline)) static inline int32_t
basicmath___ieee754_rem_pio2f(float x, float *y) {
float z, w, t, r, fn;
int32_t i, j, n, ix, hx;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix <= 0x3f490fd8) { /* |x| ~<= pi/4 , no need for reduction */
y[0] = x;
y[1] = 0;
return 0;
}
if (ix < 0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
if (hx > 0) {
z = x - basicmath_pio2_1;
if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */
y[0] = z - basicmath_pio2_1t;
y[1] = (z - y[0]) - basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z -= basicmath_pio2_2;
y[0] = z - basicmath_pio2_2t;
y[1] = (z - y[0]) - basicmath_pio2_2t;
}
return 1;
} else { /* negative x */
z = x + basicmath_pio2_1;
if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */
y[0] = z + basicmath_pio2_1t;
y[1] = (z - y[0]) + basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z += basicmath_pio2_2;
y[0] = z + basicmath_pio2_2t;
y[1] = (z - y[0]) + basicmath_pio2_2t;
}
return -1;
}
}
if (ix <= 0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
t = basicmath___fabsf(x);
n = (int32_t) (t * basicmath_invpio2 + basicmath_half);
fn = (float) n;
r = t - fn * basicmath_pio2_1;
w = fn * basicmath_pio2_1t; /* 1st round good to 40 bit */
if (n < 32 &&
(int32_t) (ix & 0xffffff00) != basicmath_npio2_hw[n - 1]) {
y[0] = r - w; /* quick check no cancellation */
} else {
u_int32_t high;
j = ix >> 23;
y[0] = r - w;
GET_FLOAT_WORD(high, y[0]);
i = j - ((high >> 23) & 0xff);
if (i > 8) { /* 2nd iteration needed, good to 57 */
t = r;
w = fn * basicmath_pio2_2;
r = t - w;
w = fn * basicmath_pio2_2t - ((t - r) - w);
y[0] = r - w;
GET_FLOAT_WORD(high, y[0]);
i = j - ((high >> 23) & 0xff);
if (i > 25) { /* 3rd iteration need, 74 bits acc */
t = r; /* will cover all possible cases */
w = fn * basicmath_pio2_3;
r = t - w;
w = fn * basicmath_pio2_3t - ((t - r) - w);
y[0] = r - w;
}
}
}
y[1] = (r - y[0]) - w;
if (hx < 0) {
y[0] = -y[0];
y[1] = -y[1];
return -n;
} else
return n;
}
/*
all other (large) arguments
*/
if (ix >= 0x7f800000) { /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
// This will never happen in basicmath_small, because
// up to this point we have already returned a value
// for each of the possible inputs
y[0] = y[1] = x - x; /* dummy initialization */
return 0;
}
/* e_sqrtf.c -- float version of e_sqrt.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
__attribute__((always_inline)) static inline float
basicmath___ieee754_sqrtf(float x) {
float z;
int32_t sign = (int) 0x80000000;
int32_t ix, s, q, m, t, i;
u_int32_t r;
GET_FLOAT_WORD(ix, x);
/* take care of Inf and NaN */
if ((ix & 0x7f800000) == 0x7f800000) {
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if (ix <= 0) {
if ((ix & (~sign)) == 0)
return x; /* sqrt(+-0) = +-0 */
else if (ix < 0)
return (x - x) / (x - x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix >> 23);
if (m == 0) { /* subnormal x */
__pragma_loopbound(0, 0);
for (i = 0; (ix & 0x00800000) == 0; i++)
ix <<= 1;
m -= i - 1;
}
m -= 127; /* unbias exponent */
ix = (ix & 0x007fffff) | 0x00800000;
if (m & 1) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
__pragma_loopbound(25, 25);
while (r != 0) {
t = s + r;
if (t <= ix) {
s = t + r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
/* use floating add to find out rounding direction */
if (ix != 0) {
z = basicmath_one - basicmath_tiny; /* trigger inexact flag */
if (z >= basicmath_one) {
z = basicmath_one + basicmath_tiny;
if (z > basicmath_one)
q += 2;
else
q += (q & 1);
}
}
ix = (q >> 1) + 0x3f000000;
ix += (m << 23);
SET_FLOAT_WORD(z, ix);
return z;
}
/* k_cosf.c -- float version of k_cos.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
basicmath_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
basicmath_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
basicmath_C4 = -2.7557314297e-07f, /* 0xb493f27c */
basicmath_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
basicmath_C6 = -1.1359647598e-11f; /* 0xad47d74e */
__attribute__((always_inline)) static inline float
basicmath___kernel_cosf(float x, float y) {
float a, hz, z, r, qx;
int32_t ix;
GET_FLOAT_WORD(ix, x);
ix &= 0x7fffffff; /* ix = |x|'s high word*/
if (ix < 0x32000000) { /* if x < 2**27 */
if (((int) x) == 0)
return basicmath_one; /* generate inexact */
}
z = x * x;
r = z * (basicmath_C1 +
z * (basicmath_C2 +
z * (basicmath_C3 +
z * (basicmath_C4 +
z * (basicmath_C5 + z * basicmath_C6)))));
if (ix < 0x3e99999a) /* if |x| < 0.3 */
return basicmath_one - ((float) 0.5f * z - (z * r - x * y));
else {
if (ix > 0x3f480000) /* x > 0.78125 */
qx = (float) 0.28125f;
else {
SET_FLOAT_WORD(qx, ix - 0x01000000); /* x/4 */
}
hz = (float) 0.5f * z - qx;
a = basicmath_one - qx;
return a - (hz - (z * r - x * y));
}
}
/* k_sinf.c -- float version of k_sin.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
basicmath_S2 = 8.3333337680e-03f, /* 0x3c088889 */
basicmath_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
basicmath_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
basicmath_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
basicmath_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
__attribute__((always_inline)) static inline float
basicmath___kernel_sinf(float x, float y, int iy) {
float z, r, v;
int32_t ix;
GET_FLOAT_WORD(ix, x);
ix &= 0x7fffffff; /* high word of x */
if (ix < 0x32000000) { /* |x| < 2**-27 */
if ((int) x == 0)
return x; /* generate inexact */
}
z = x * x;
v = z * x;
r = basicmath_S2 +
z * (basicmath_S3 +
z * (basicmath_S4 + z * (basicmath_S5 + z * basicmath_S6)));
if (iy == 0)
return x + v * (basicmath_S1 + z * r);
else
return x - ((z * (basicmath_half * y - v * r) - y) - v * basicmath_S1);
}
/* s_copysignf.c -- float version of s_copysign.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
copysignf(float x, float y)
copysignf(x,y) returns a value with the magnitude of x and
with the sign bit of y.
*/
__attribute__((always_inline)) static inline float
basicmath___copysignf(float x, float y) {
u_int32_t ix, iy;
GET_FLOAT_WORD(ix, x);
GET_FLOAT_WORD(iy, y);
SET_FLOAT_WORD(x, (ix & 0x7fffffff) | (iy & 0x80000000));
return x;
}
/* s_cosf.c -- float version of s_cos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
__attribute__((always_inline)) static inline float
basicmath___cosf(float x) {
float y[2], z = 0.0f;
int32_t n, ix;
GET_FLOAT_WORD(ix, x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if (ix <= 0x3f490fd8)
return basicmath___kernel_cosf(x, z);
/* cos(Inf or NaN) is NaN */
else if (ix >= 0x7f800000)
return x - x;
/* argument reduction needed */
else {
n = basicmath___ieee754_rem_pio2f(x, y);
switch (n & 3) {
case 0:
return basicmath___kernel_cosf(y[0], y[1]);
case 1:
return -basicmath___kernel_sinf(y[0], y[1], 1);
case 2:
return -basicmath___kernel_cosf(y[0], y[1]);
default:
return basicmath___kernel_sinf(y[0], y[1], 1);
}
}
}
/* s_fabsf.c -- float version of s_fabs.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
fabsf(x) returns the absolute value of x.
*/
__attribute__((always_inline)) static inline float
basicmath___fabsf(float x) {
u_int32_t ix;
GET_FLOAT_WORD(ix, x);
SET_FLOAT_WORD(x, ix & 0x7fffffff);
return x;
}
/*
isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
no branching!
*/
__attribute__((always_inline)) static inline int
basicmath___isinff(float x) {
int32_t ix, t;
GET_FLOAT_WORD(ix, x);
t = ix & 0x7fffffff;
t ^= 0x7f800000;
t |= -t;
return ~(t >> 31) & (ix >> 30);
}
/* s_scalbnf.c -- float version of s_scalbn.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_two25 = 3.355443200e+07f, /* 0x4c000000 */
basicmath_twom25 = 2.9802322388e-08f; /* 0x33000000 */
__attribute__((always_inline)) static inline float
basicmath___scalbnf(float x, int n) {
int32_t k, ix;
GET_FLOAT_WORD(ix, x);
k = (ix & 0x7f800000) >> 23; /* extract exponent */
if (k == 0) { /* 0 or subnormal x */
if ((ix & 0x7fffffff) == 0)
return x; /* +-0 */
x *= basicmath_two25;
GET_FLOAT_WORD(ix, x);
k = ((ix & 0x7f800000) >> 23) - 25;
}
if (k == 0xff)
return x + x; /* NaN or Inf */
k = k + n;
if (n > 50000 || k > 0xfe)
return basicmath_huge *
basicmath___copysignf(basicmath_huge, x); /* overflow */
if (n < -50000)
return basicmath_tiny *
basicmath___copysignf(basicmath_tiny, x); /*underflow*/
if (k > 0) { /* normal result */
SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
return x;
}
if (k <= -25)
return basicmath_tiny *
basicmath___copysignf(basicmath_tiny, x); /*underflow*/
k += 25; /* subnormal result */
SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
return x * basicmath_twom25;
}

View File

@ -0,0 +1,66 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _WCCLIBM
#define _WCCLIBM
#define int32_t int
#define u_int32_t unsigned int
// Often used variables/consts
static const float basicmath_one = 1.0f, basicmath_tiny = 1.0e-30f,
basicmath_half = 5.0000000000e-01, /* 0x3f000000 */
basicmath_huge = 1.0e30, basicmath_two = 2.0,
basicmath_two24 = 16777216.0, /* 0x4b800000 */
basicmath_zero = 0.0;
__attribute__((always_inline)) static inline float
basicmath___copysignf(float x, float y);
__attribute__((always_inline)) static inline float basicmath___cosf(float x);
__attribute__((always_inline)) static inline float basicmath___fabsf(float x);
__attribute__((always_inline)) static inline float
basicmath___ieee754_acosf(float x);
__attribute__((always_inline)) static inline float
basicmath___ieee754_powf(float x, float y);
__attribute__((always_inline)) static inline int32_t
basicmath___ieee754_rem_pio2f(float x, float *y);
__attribute__((always_inline)) static inline float
basicmath___ieee754_sqrtf(float x);
__attribute__((always_inline)) static inline int basicmath___isinff(float x);
__attribute__((always_inline)) static inline float
basicmath___kernel_cosf(float x, float y);
__attribute__((always_inline)) static inline float
basicmath___kernel_sinf(float x, float y, int iy);
__attribute__((always_inline)) static inline float basicmath___scalbnf(float x,
int n);
#endif // _WCCLIBM

View File

@ -0,0 +1,68 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
from: @(#)fdlibm.h 5.1 93/09/24
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: math_private.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: fdlibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _MATH_PRIVATE_H_
#define _MATH_PRIVATE_H_
#include "wcclibm.h"
/* A union which permits us to convert between a float and a 32 bit int. */
typedef union {
float value;
u_int32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i,d) \
{ \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
}
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,i) \
{ \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
}
#endif /* _MATH_PRIVATE_H_ */

View File

@ -0,0 +1,757 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.c
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.c
Changes: No major functional changes.
License: See the terms above.
*/
#include "wcclibm.h"
#include "math_private.h"
/* e_acosf.c -- float version of e_acos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_pi = 3.1415925026e+00f, /* 0x40490fda */
basicmath_pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */
basicmath_pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */
basicmath_pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_pS1 = -3.2556581497e-01f, /* 0xbea6b090 */
basicmath_pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */
basicmath_pS3 = -4.0055535734e-02f, /* 0xbd241146 */
basicmath_pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */
basicmath_pS5 = 3.4793309169e-05f, /* 0x3811ef08 */
basicmath_qS1 = -2.4033949375e+00f, /* 0xc019d139 */
basicmath_qS2 = 2.0209457874e+00f, /* 0x4001572d */
basicmath_qS3 = -6.8828397989e-01f, /* 0xbf303361 */
basicmath_qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */
float basicmath___ieee754_acosf( float x )
{
float z, p, q, r, w, s, c, df;
int32_t hx, ix;
GET_FLOAT_WORD( hx, x );
ix = hx & 0x7fffffff;
if ( ix == 0x3f800000 ) { /* |x|==1 */
if ( hx > 0 ) return 0.0f; /* acos(1) = 0 */
else return basicmath_pi + ( float )2.0f * basicmath_pio2_lo; /* acos(-1)= pi */
} else
if ( ix > 0x3f800000 ) { /* |x| >= 1 */
return ( x - x ) / ( x - x ); /* acos(|x|>1) is NaN */
}
if ( ix < 0x3f000000 ) { /* |x| < 0.5 */
if ( ix <= 0x23000000 ) return basicmath_pio2_hi +
basicmath_pio2_lo; /*if|x|<2**-57*/
z = x * x;
p = z * ( basicmath_pS0 + z * ( basicmath_pS1 + z * ( basicmath_pS2 + z *
( basicmath_pS3 + z *
( basicmath_pS4 + z * basicmath_pS5 ) ) ) ) );
q = basicmath_one + z * ( basicmath_qS1 + z * ( basicmath_qS2 + z *
( basicmath_qS3 + z * basicmath_qS4 ) ) );
r = p / q;
return basicmath_pio2_hi - ( x - ( basicmath_pio2_lo - x * r ) );
} else
if ( hx < 0 ) { /* x < -0.5 */
z = ( basicmath_one + x ) * ( float )0.5f;
p = z * ( basicmath_pS0 + z * ( basicmath_pS1 + z * ( basicmath_pS2 + z *
( basicmath_pS3 + z *
( basicmath_pS4 + z * basicmath_pS5 ) ) ) ) );
q = basicmath_one + z * ( basicmath_qS1 + z * ( basicmath_qS2 + z *
( basicmath_qS3 + z * basicmath_qS4 ) ) );
s = basicmath___ieee754_sqrtf( z );
r = p / q;
w = r * s - basicmath_pio2_lo;
return basicmath_pi - ( float )2.0f * ( s + w );
} else { /* x > 0.5 */
int32_t idf;
z = ( basicmath_one - x ) * ( float )0.5f;
s = basicmath___ieee754_sqrtf( z );
df = s;
GET_FLOAT_WORD( idf, df );
SET_FLOAT_WORD( df, idf & 0xfffff000 );
c = ( z - df * df ) / ( s + df );
p = z * ( basicmath_pS0 + z * ( basicmath_pS1 + z * ( basicmath_pS2 + z *
( basicmath_pS3 + z *
( basicmath_pS4 + z * basicmath_pS5 ) ) ) ) );
q = basicmath_one + z * ( basicmath_qS1 + z * ( basicmath_qS2 + z *
( basicmath_qS3 + z * basicmath_qS4 ) ) );
r = p / q;
w = r * s + c;
return ( float )2.0f * ( df + w );
}
}
/* e_powf.c -- float version of e_pow.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_bp[] = {1.0f, 1.5f,},
basicmath_dp_h[] = { 0.0f, 5.84960938e-01f,}, /* 0x3f15c000 */
basicmath_dp_l[] = { 0.0f, 1.56322085e-06f,}, /* 0x35d1cfdc */
/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
basicmath_L1 = 6.0000002384e-01f, /* 0x3f19999a */
basicmath_L2 = 4.2857143283e-01f, /* 0x3edb6db7 */
basicmath_L3 = 3.3333334327e-01f, /* 0x3eaaaaab */
basicmath_L4 = 2.7272811532e-01f, /* 0x3e8ba305 */
basicmath_L5 = 2.3066075146e-01f, /* 0x3e6c3255 */
basicmath_L6 = 2.0697501302e-01f, /* 0x3e53f142 */
basicmath_P1 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_P2 = -2.7777778450e-03f, /* 0xbb360b61 */
basicmath_P3 = 6.6137559770e-05f, /* 0x388ab355 */
basicmath_P4 = -1.6533901999e-06f, /* 0xb5ddea0e */
basicmath_P5 = 4.1381369442e-08f, /* 0x3331bb4c */
basicmath_lg2 = 6.9314718246e-01f, /* 0x3f317218 */
basicmath_lg2_h = 6.93145752e-01f, /* 0x3f317200 */
basicmath_lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */
basicmath_ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */
basicmath_cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */
basicmath_cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */
basicmath_cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */
basicmath_ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */
basicmath_ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/
basicmath_ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/
float basicmath___ieee754_powf( float x, float y )
{
float z, ax, z_h, z_l, p_h, p_l;
float y1, t1, t2, r, s, t, u, v, w;
int32_t i, j, k, yisint, n;
int32_t hx, hy, ix, iy, is;
GET_FLOAT_WORD( hx, x );
GET_FLOAT_WORD( hy, y );
ix = hx & 0x7fffffff;
iy = hy & 0x7fffffff;
/* y==zero: x**0 = 1 */
if ( iy == 0 ) return basicmath_one;
/* x==+-1 */
if ( x == 1.0f ) return basicmath_one;
if ( x == -1.0f && basicmath___isinff( y ) ) return basicmath_one;
/* +-NaN return x+y */
if ( ix > 0x7f800000 ||
iy > 0x7f800000 )
return x + y;
/* determine if y is an odd int when x < 0
yisint = 0 ... y is not an integer
yisint = 1 ... y is an odd int
yisint = 2 ... y is an even int
*/
yisint = 0;
if ( hx < 0 ) {
if ( iy >= 0x4b800000 ) yisint = 2; /* even integer y */
else
if ( iy >= 0x3f800000 ) {
k = ( iy >> 23 ) - 0x7f; /* exponent */
j = iy >> ( 23 - k );
if ( ( j << ( 23 - k ) ) == iy ) yisint = 2 - ( j & 1 );
}
}
/* special value of y */
if ( iy == 0x7f800000 ) { /* y is +-inf */
if ( ix == 0x3f800000 )
return y - y; /* inf**+-1 is NaN */
else
if ( ix > 0x3f800000 ) /* (|x|>1)**+-inf = inf,0 */
return ( hy >= 0 ) ? y : basicmath_zero;
else /* (|x|<1)**-,+inf = inf,0 */
return ( hy < 0 ) ? -y : basicmath_zero;
}
if ( iy == 0x3f800000 ) { /* y is +-1 */
if ( hy < 0 ) return basicmath_one / x;
else return x;
}
if ( hy == 0x40000000 ) return x * x; /* y is 2 */
if ( hy == 0x3f000000 ) { /* y is 0.5 */
if ( hx >= 0 ) /* x >= +0 */
return basicmath___ieee754_sqrtf( x );
}
ax = basicmath___fabsf( x );
/* special value of x */
if ( ix == 0x7f800000 || ix == 0 || ix == 0x3f800000 ) {
z = ax; /*x is +-0,+-inf,+-1*/
if ( hy < 0 ) z = basicmath_one / z; /* z = (1/|x|) */
if ( hx < 0 ) {
if ( ( ( ix - 0x3f800000 ) | yisint ) == 0 ) {
z = ( z - z ) / ( z - z ); /* (-1)**non-int is NaN */
} else
if ( yisint == 1 )
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
/* (x<0)**(non-int) is NaN */
if ( ( ( ( ( u_int32_t )hx >> 31 ) - 1 ) | yisint ) == 0 ) return ( x - x ) /
( x - x );
/* |y| is huge */
if ( iy > 0x4d000000 ) { /* if |y| > 2**27 */
/* over/underflow if x is not close to one */
if ( ix < 0x3f7ffff8 ) return ( hy < 0 ) ? basicmath_huge * basicmath_huge :
basicmath_tiny * basicmath_tiny;
if ( ix > 0x3f800007 ) return ( hy > 0 ) ? basicmath_huge * basicmath_huge :
basicmath_tiny * basicmath_tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = x - 1; /* t has 20 trailing zeros */
w = ( t * t ) * ( ( float )0.5f - t * ( ( float )0.333333333333f - t *
( float )0.25f ) );
u = basicmath_ivln2_h * t; /* ivln2_h has 16 sig. bits */
v = t * basicmath_ivln2_l - w * basicmath_ivln2;
t1 = u + v;
GET_FLOAT_WORD( is, t1 );
SET_FLOAT_WORD( t1, is & 0xfffff000 );
t2 = v - ( t1 - u );
} else {
float s2, s_h, s_l, t_h, t_l;
n = 0;
/* take care subnormal number */
if ( ix < 0x00800000 ) {
ax *= basicmath_two24;
n -= 24;
GET_FLOAT_WORD( ix, ax );
}
n += ( ( ix ) >> 23 ) - 0x7f;
j = ix & 0x007fffff;
/* determine interval */
ix = j | 0x3f800000; /* normalize ix */
if ( j <= 0x1cc471 ) k = 0; /* |x|<sqrt(3/2) */
else
if ( j < 0x5db3d7 ) k = 1; /* |x|<sqrt(3) */
else {
k = 0;
n += 1;
ix -= 0x00800000;
}
SET_FLOAT_WORD( ax, ix );
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
u = ax - basicmath_bp[ k ]; /* bp[0]=1.0, bp[1]=1.5 */
v = basicmath_one / ( ax + basicmath_bp[ k ] );
s = u * v;
s_h = s;
GET_FLOAT_WORD( is, s_h );
SET_FLOAT_WORD( s_h, is & 0xfffff000 );
/* t_h=ax+bp[k] High */
SET_FLOAT_WORD( t_h, ( ( ix >> 1 ) | 0x20000000 ) + 0x0040000 + ( k << 21 ) );
t_l = ax - ( t_h - basicmath_bp[ k ] );
s_l = v * ( ( u - s_h * t_h ) - s_h * t_l );
/* compute log(ax) */
s2 = s * s;
r = s2 * s2 * ( basicmath_L1 + s2 * ( basicmath_L2 + s2 *
( basicmath_L3 + s2 * ( basicmath_L4 + s2 *
( basicmath_L5 + s2 * basicmath_L6 ) ) ) ) );
r += s_l * ( s_h + s );
s2 = s_h * s_h;
t_h = ( float )3.0f + s2 + r;
GET_FLOAT_WORD( is, t_h );
SET_FLOAT_WORD( t_h, is & 0xfffff000 );
t_l = r - ( ( t_h - ( float )3.0f ) - s2 );
/* u+v = s*(1+...) */
u = s_h * t_h;
v = s_l * t_h + t_l * s;
/* 2/(3log2)*(s+...) */
p_h = u + v;
GET_FLOAT_WORD( is, p_h );
SET_FLOAT_WORD( p_h, is & 0xfffff000 );
p_l = v - ( p_h - u );
z_h = basicmath_cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = basicmath_cp_l * p_h + p_l * basicmath_cp + basicmath_dp_l[ k ];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = ( float )n;
t1 = ( ( ( z_h + z_l ) + basicmath_dp_h[ k ] ) + t );
GET_FLOAT_WORD( is, t1 );
SET_FLOAT_WORD( t1, is & 0xfffff000 );
t2 = z_l - ( ( ( t1 - t ) - basicmath_dp_h[ k ] ) - z_h );
}
s = basicmath_one; /* s (sign of result -ve**odd) = -1 else = 1 */
if ( ( ( ( ( u_int32_t )hx >> 31 ) - 1 ) | ( yisint - 1 ) ) == 0 )
s = -basicmath_one; /* (-ve)**(odd int) */
/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
GET_FLOAT_WORD( is, y );
SET_FLOAT_WORD( y1, is & 0xfffff000 );
p_l = ( y - y1 ) * t1 + y * t2;
p_h = y1 * t1;
z = p_l + p_h;
GET_FLOAT_WORD( j, z );
if ( j > 0x43000000 ) /* if z > 128 */
return s * basicmath_huge * basicmath_huge; /* overflow */
else
if ( j == 0x43000000 ) { /* if z == 128 */
if ( p_l + basicmath_ovt > z - p_h ) return s * basicmath_huge *
basicmath_huge; /* overflow */
} else
if ( ( j & 0x7fffffff ) > 0x43160000 ) /* z <= -150 */
return s * basicmath_tiny * basicmath_tiny; /* underflow */
else
if ( ( u_int32_t ) j == 0xc3160000 ) { /* z == -150 */
if ( p_l <= z - p_h ) return s * basicmath_tiny *
basicmath_tiny; /* underflow */
}
/*
compute 2**(p_h+p_l)
*/
i = j & 0x7fffffff;
k = ( i >> 23 ) - 0x7f;
n = 0;
if ( i > 0x3f000000 ) { /* if |z| > 0.5, set n = [z+0.5] */
n = j + ( 0x00800000 >> ( k + 1 ) );
k = ( ( n & 0x7fffffff ) >> 23 ) - 0x7f; /* new k for n */
SET_FLOAT_WORD( t, n & ~( 0x007fffff >> k ) );
n = ( ( n & 0x007fffff ) | 0x00800000 ) >> ( 23 - k );
if ( j < 0 ) n = -n;
p_h -= t;
}
t = p_l + p_h;
GET_FLOAT_WORD( is, t );
SET_FLOAT_WORD( t, is & 0xfffff000 );
u = t * basicmath_lg2_h;
v = ( p_l - ( t - p_h ) ) * basicmath_lg2 + t * basicmath_lg2_l;
z = u + v;
w = v - ( z - u );
t = z * z;
t1 = z - t * ( basicmath_P1 + t * ( basicmath_P2 + t * ( basicmath_P3 + t *
( basicmath_P4 + t * basicmath_P5 ) ) ) );
r = ( z * t1 ) / ( t1 - basicmath_two ) - ( w + z * w );
z = basicmath_one - ( r - z );
GET_FLOAT_WORD( j, z );
j += ( n << 23 );
if ( ( j >> 23 ) <= 0 ) z = basicmath___scalbnf( z, n ); /* subnormal output */
else SET_FLOAT_WORD( z, j );
return s * z;
}
/* e_rem_pio2f.c -- float version of e_rem_pio2.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/* basicmath___ieee754_rem_pio2f(x,y)
return the remainder of x rem pi/2 in y[0]+y[1]
*/
/* This array is like the one in e_rem_pio2.c, but the numbers are
single precision and the last 8 bits are forced to 0. */
static const int32_t basicmath_npio2_hw[] = {
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
0x4242c700, 0x42490f00
};
/*
invpio2: 24 bits of 2/pi
pio2_1: first 17 bit of pi/2
pio2_1t: pi/2 - pio2_1
pio2_2: second 17 bit of pi/2
pio2_2t: pi/2 - (pio2_1+pio2_2)
pio2_3: third 17 bit of pi/2
pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const float basicmath_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
basicmath_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
basicmath_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
basicmath_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
basicmath_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
basicmath_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
basicmath_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
int32_t basicmath___ieee754_rem_pio2f( float x, float *y )
{
float z, w, t, r, fn;
int32_t i, j, n, ix, hx;
GET_FLOAT_WORD( hx, x );
ix = hx & 0x7fffffff;
if ( ix <= 0x3f490fd8 ) { /* |x| ~<= pi/4 , no need for reduction */
y[ 0 ] = x;
y[ 1 ] = 0;
return 0;
}
if ( ix < 0x4016cbe4 ) { /* |x| < 3pi/4, special case with n=+-1 */
if ( hx > 0 ) {
z = x - basicmath_pio2_1;
if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) { /* 24+24 bit pi OK */
y[ 0 ] = z - basicmath_pio2_1t;
y[ 1 ] = ( z - y[ 0 ] ) - basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z -= basicmath_pio2_2;
y[ 0 ] = z - basicmath_pio2_2t;
y[ 1 ] = ( z - y[ 0 ] ) - basicmath_pio2_2t;
}
return 1;
} else { /* negative x */
z = x + basicmath_pio2_1;
if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) { /* 24+24 bit pi OK */
y[ 0 ] = z + basicmath_pio2_1t;
y[ 1 ] = ( z - y[ 0 ] ) + basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z += basicmath_pio2_2;
y[ 0 ] = z + basicmath_pio2_2t;
y[ 1 ] = ( z - y[ 0 ] ) + basicmath_pio2_2t;
}
return -1;
}
}
if ( ix <= 0x43490f80 ) { /* |x| ~<= 2^7*(pi/2), medium size */
t = basicmath___fabsf( x );
n = ( int32_t ) ( t * basicmath_invpio2 + basicmath_half );
fn = ( float )n;
r = t - fn * basicmath_pio2_1;
w = fn * basicmath_pio2_1t; /* 1st round good to 40 bit */
if ( n < 32 && ( int32_t )( ix & 0xffffff00 ) != basicmath_npio2_hw[n - 1] ) {
y[ 0 ] = r - w; /* quick check no cancellation */
} else {
u_int32_t high;
j = ix >> 23;
y[ 0 ] = r - w;
GET_FLOAT_WORD( high, y[ 0 ] );
i = j - ( ( high >> 23 ) & 0xff );
if ( i > 8 ) { /* 2nd iteration needed, good to 57 */
t = r;
w = fn * basicmath_pio2_2;
r = t - w;
w = fn * basicmath_pio2_2t - ( ( t - r ) - w );
y[ 0 ] = r - w;
GET_FLOAT_WORD( high, y[ 0 ] );
i = j - ( ( high >> 23 ) & 0xff );
if ( i > 25 ) { /* 3rd iteration need, 74 bits acc */
t = r; /* will cover all possible cases */
w = fn * basicmath_pio2_3;
r = t - w;
w = fn * basicmath_pio2_3t - ( ( t - r ) - w );
y[ 0 ] = r - w;
}
}
}
y[ 1 ] = ( r - y[ 0 ] ) - w;
if ( hx < 0 ) {
y[ 0 ] = -y[ 0 ];
y[ 1 ] = -y[ 1 ];
return -n;
} else return n;
}
/*
all other (large) arguments
*/
if ( ix >= 0x7f800000 ) { /* x is inf or NaN */
y[ 0 ] = y[ 1 ] = x - x;
return 0;
}
// This will never happen in basicmath_small, because
// up to this point we have already returned a value
// for each of the possible inputs
y[ 0 ] = y[ 1 ] = x - x; /* dummy initialization */
return 0;
}
/* e_sqrtf.c -- float version of e_sqrt.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
float basicmath___ieee754_sqrtf( float x )
{
float z;
int32_t sign = ( int )0x80000000;
int32_t ix, s, q, m, t, i;
u_int32_t r;
GET_FLOAT_WORD( ix, x );
/* take care of Inf and NaN */
if ( ( ix & 0x7f800000 ) == 0x7f800000 ) {
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if ( ix <= 0 ) {
if ( ( ix & ( ~sign ) ) == 0 ) return x; /* sqrt(+-0) = +-0 */
else
if ( ix < 0 )
return ( x - x ) / ( x - x ); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = ( ix >> 23 );
if ( m == 0 ) { /* subnormal x */
_Pragma( "loopbound min 0 max 0" )
for ( i = 0; ( ix & 0x00800000 ) == 0; i++ )
ix <<= 1;
m -= i - 1;
}
m -= 127; /* unbias exponent */
ix = ( ix & 0x007fffff ) | 0x00800000;
if ( m & 1 ) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
_Pragma( "loopbound min 25 max 25" )
while ( r != 0 ) {
t = s + r;
if ( t <= ix ) {
s = t + r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
/* use floating add to find out rounding direction */
if ( ix != 0 ) {
z = basicmath_one - basicmath_tiny; /* trigger inexact flag */
if ( z >= basicmath_one ) {
z = basicmath_one + basicmath_tiny;
if ( z > basicmath_one )
q += 2;
else
q += ( q & 1 );
}
}
ix = ( q >> 1 ) + 0x3f000000;
ix += ( m << 23 );
SET_FLOAT_WORD( z, ix );
return z;
}
/* k_cosf.c -- float version of k_cos.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
basicmath_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
basicmath_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
basicmath_C4 = -2.7557314297e-07f, /* 0xb493f27c */
basicmath_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
basicmath_C6 = -1.1359647598e-11f; /* 0xad47d74e */
float basicmath___kernel_cosf( float x, float y )
{
float a, hz, z, r, qx;
int32_t ix;
GET_FLOAT_WORD( ix, x );
ix &= 0x7fffffff; /* ix = |x|'s high word*/
if ( ix < 0x32000000 ) { /* if x < 2**27 */
if ( ( ( int )x ) == 0 ) return basicmath_one; /* generate inexact */
}
z = x * x;
r = z * ( basicmath_C1 + z * ( basicmath_C2 + z * ( basicmath_C3 + z *
( basicmath_C4 + z * ( basicmath_C5 + z * basicmath_C6 ) ) ) ) );
if ( ix < 0x3e99999a ) /* if |x| < 0.3 */
return basicmath_one - ( ( float )0.5f * z - ( z * r - x * y ) );
else {
if ( ix > 0x3f480000 ) /* x > 0.78125 */
qx = ( float )0.28125f;
else {
SET_FLOAT_WORD( qx, ix - 0x01000000 ); /* x/4 */
}
hz = ( float )0.5f * z - qx;
a = basicmath_one - qx;
return a - ( hz - ( z * r - x * y ) );
}
}
/* k_sinf.c -- float version of k_sin.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
basicmath_S2 = 8.3333337680e-03f, /* 0x3c088889 */
basicmath_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
basicmath_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
basicmath_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
basicmath_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
float basicmath___kernel_sinf( float x, float y, int iy )
{
float z, r, v;
int32_t ix;
GET_FLOAT_WORD( ix, x );
ix &= 0x7fffffff; /* high word of x */
if ( ix < 0x32000000 ) { /* |x| < 2**-27 */
if ( ( int )x == 0 ) return x; /* generate inexact */
}
z = x * x;
v = z * x;
r = basicmath_S2 + z * ( basicmath_S3 + z * ( basicmath_S4 + z *
( basicmath_S5 + z * basicmath_S6 ) ) );
if ( iy == 0 ) return x + v * ( basicmath_S1 + z * r );
else return x - ( ( z * ( basicmath_half * y - v * r ) - y ) - v *
basicmath_S1 );
}
/* s_copysignf.c -- float version of s_copysign.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
copysignf(float x, float y)
copysignf(x,y) returns a value with the magnitude of x and
with the sign bit of y.
*/
float basicmath___copysignf( float x, float y )
{
u_int32_t ix, iy;
GET_FLOAT_WORD( ix, x );
GET_FLOAT_WORD( iy, y );
SET_FLOAT_WORD( x, ( ix & 0x7fffffff ) | ( iy & 0x80000000 ) );
return x;
}
/* s_cosf.c -- float version of s_cos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
float basicmath___cosf( float x )
{
float y[ 2 ], z = 0.0f;
int32_t n, ix;
GET_FLOAT_WORD( ix, x );
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if ( ix <= 0x3f490fd8 ) return basicmath___kernel_cosf( x, z );
/* cos(Inf or NaN) is NaN */
else
if ( ix >= 0x7f800000 ) return x - x;
/* argument reduction needed */
else {
n = basicmath___ieee754_rem_pio2f( x, y );
switch ( n & 3 ) {
case 0:
return basicmath___kernel_cosf( y[ 0 ], y[ 1 ] );
case 1:
return -basicmath___kernel_sinf( y[ 0 ], y[ 1 ], 1 );
case 2:
return -basicmath___kernel_cosf( y[ 0 ], y[ 1 ] );
default:
return basicmath___kernel_sinf( y[ 0 ], y[ 1 ], 1 );
}
}
}
/* s_fabsf.c -- float version of s_fabs.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
fabsf(x) returns the absolute value of x.
*/
float basicmath___fabsf( float x )
{
u_int32_t ix;
GET_FLOAT_WORD( ix, x );
SET_FLOAT_WORD( x, ix & 0x7fffffff );
return x;
}
/*
isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
no branching!
*/
int basicmath___isinff ( float x )
{
int32_t ix, t;
GET_FLOAT_WORD( ix, x );
t = ix & 0x7fffffff;
t ^= 0x7f800000;
t |= -t;
return ~( t >> 31 ) & ( ix >> 30 );
}
/* s_scalbnf.c -- float version of s_scalbn.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_two25 = 3.355443200e+07f, /* 0x4c000000 */
basicmath_twom25 = 2.9802322388e-08f; /* 0x33000000 */
float basicmath___scalbnf ( float x, int n )
{
int32_t k, ix;
GET_FLOAT_WORD( ix, x );
k = ( ix & 0x7f800000 ) >> 23; /* extract exponent */
if ( k == 0 ) { /* 0 or subnormal x */
if ( ( ix & 0x7fffffff ) == 0 ) return x; /* +-0 */
x *= basicmath_two25;
GET_FLOAT_WORD( ix, x );
k = ( ( ix & 0x7f800000 ) >> 23 ) - 25;
}
if ( k == 0xff ) return x + x; /* NaN or Inf */
k = k + n;
if ( n > 50000 || k > 0xfe )
return basicmath_huge * basicmath___copysignf( basicmath_huge,
x ); /* overflow */
if ( n < -50000 )
return basicmath_tiny * basicmath___copysignf( basicmath_tiny,
x ); /*underflow*/
if ( k > 0 ) { /* normal result */
SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) );
return x;
}
if ( k <= -25 )
return basicmath_tiny * basicmath___copysignf( basicmath_tiny,
x ); /*underflow*/
k += 25; /* subnormal result */
SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) );
return x * basicmath_twom25;
}

View File

@ -0,0 +1,61 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _WCCLIBM
#define _WCCLIBM
#define int32_t int
#define u_int32_t unsigned int
// Often used variables/consts
static const float basicmath_one = 1.0f,
basicmath_tiny = 1.0e-30f,
basicmath_half = 5.0000000000e-01, /* 0x3f000000 */
basicmath_huge = 1.0e30,
basicmath_two = 2.0,
basicmath_two24 = 16777216.0, /* 0x4b800000 */
basicmath_zero = 0.0;
float basicmath___copysignf( float x, float y );
float basicmath___cosf( float x );
float basicmath___fabsf( float x );
float basicmath___ieee754_acosf( float x );
float basicmath___ieee754_powf( float x, float y );
int32_t basicmath___ieee754_rem_pio2f( float x, float *y );
float basicmath___ieee754_sqrtf( float x );
int basicmath___isinff ( float x );
float basicmath___kernel_cosf( float x, float y );
float basicmath___kernel_sinf( float x, float y, int iy );
float basicmath___scalbnf ( float x, int n );
#endif // _WCCLIBM

View File

@ -0,0 +1,25 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(countnegative)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/countnegative.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/countnegative.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,29 @@
File: countnegative.c
Original provenience: Mälardalen benchmark suite, www.mrtc.....
2015-11-26:
- Changed return type of InitSeed, Initialize, and Test to void
because the result was ignored anyway
- Prefixed all functions and global variables with "countnegative_"
- Added new function countnegative_return computing a checksum as
return value
- Separated initialization (called from countnegative_init) from
actual computation (called from countnegative_main), remove
pointless function countnegative_test afterwards
- Reordered functions in source code: initialization- and
return-value-related functions first, followed by algorithm core
function, followed by main functions
- Eliminated definition of macro WORSTCASE and kept only the relevant
part of the related #ifdef block
- Removed comments that referred to MAXSIZE being 100 (instead of 20)
- Made countnegative_seed volatile
- Changed C++ style comments to C style comments
- Applied code formatting with astyle as in the example
- Added general TACLeBench header to beginning of source code
2016-03-15:
- Return 0 if checksum is as expected, -1 otherwise
- Add entrypoint pragma
2016-04-20:
- Cast "expected" return value to int for comparison

View File

@ -0,0 +1,140 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: countnegative
Author: unknown
Function: Counts negative and non-negative numbers in a
matrix. Features nested loops, well-structured code.
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/cnt/cnt.c
Changes: Changed split between initialization and computation
License: May be used, modified, and re-distributed freely
*/
/*
The dimension of the matrix
*/
#define MAXSIZE 20
/*
Type definition for the matrix
*/
typedef int matrix [ MAXSIZE ][ MAXSIZE ];
/*
Forward declaration of functions
*/
void countnegative_initSeed( void );
int countnegative_randomInteger( void );
void countnegative_initialize( matrix );
void countnegative_init( void );
int countnegative_return( void );
void countnegative_sum( matrix );
void countnegative_main( void );
int main( void );
/*
Globals
*/
volatile int countnegative_seed;
matrix countnegative_array;
int countnegative_postotal, countnegative_negtotal;
int countnegative_poscnt, countnegative_negcnt;
/*
Initializes the seed used in the random number generator.
*/
void countnegative_initSeed ( void )
{
countnegative_seed = 0;
}
/*
Generates random integers between 0 and 8094
*/
int countnegative_randomInteger( void )
{
countnegative_seed = ( ( countnegative_seed * 133 ) + 81 ) % 8095;
return countnegative_seed;
}
/*
Initializes the given array with random integers.
*/
void countnegative_initialize( matrix Array )
{
register int OuterIndex, InnerIndex;
_Pragma( "loopbound min 20 max 20" )
for ( OuterIndex = 0; OuterIndex < MAXSIZE; OuterIndex++ )
_Pragma( "loopbound min 20 max 20" )
for ( InnerIndex = 0; InnerIndex < MAXSIZE; InnerIndex++ )
Array[ OuterIndex ][ InnerIndex ] = countnegative_randomInteger();
}
void countnegative_init( void )
{
countnegative_initSeed();
countnegative_initialize( countnegative_array );
}
int countnegative_return( void )
{
int checksum = ( countnegative_postotal +
countnegative_poscnt +
countnegative_negtotal +
countnegative_negcnt );
return ( ( checksum == ( int )0x1778de ) ? 0 : -1 );
}
void countnegative_sum( matrix Array )
{
register int Outer, Inner;
int Ptotal = 0; /* changed these to locals in order to drive worst case */
int Ntotal = 0;
int Pcnt = 0;
int Ncnt = 0;
_Pragma( "loopbound min 20 max 20" )
for ( Outer = 0; Outer < MAXSIZE; Outer++ )
_Pragma( "loopbound min 20 max 20" )
for ( Inner = 0; Inner < MAXSIZE; Inner++ )
if ( Array[ Outer ][ Inner ] >= 0 ) {
Ptotal += Array[ Outer ][ Inner ];
Pcnt++;
} else {
Ntotal += Array[ Outer ][ Inner ];
Ncnt++;
}
countnegative_postotal = Ptotal;
countnegative_poscnt = Pcnt;
countnegative_negtotal = Ntotal;
countnegative_negcnt = Ncnt;
}
/*
The main function
*/
void _Pragma( "entrypoint" ) countnegative_main ( void )
{
countnegative_sum( countnegative_array );
}
int main( void )
{
countnegative_init();
countnegative_main();
return ( countnegative_return() );
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,147 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: countnegative
Author: unknown
Function: Counts negative and non-negative numbers in a
matrix. Features nested loops, well-structured code.
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/cnt/cnt.c
Changes: Changed split between initialization and computation
License: May be used, modified, and re-distributed freely
*/
/*
The dimension of the matrix
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
#define MAXSIZE 20
/*
Type definition for the matrix
*/
typedef int matrix[MAXSIZE][MAXSIZE];
/*
Forward declaration of functions
*/
void countnegative_initSeed(void);
int countnegative_randomInteger(void);
void countnegative_initialize(matrix);
void countnegative_init(void);
int countnegative_return(void);
void countnegative_sum(matrix);
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
countnegative_main(void);
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
/*
Globals
*/
volatile int countnegative_seed;
matrix countnegative_array;
int countnegative_postotal, countnegative_negtotal;
int countnegative_poscnt, countnegative_negcnt;
/*
Initializes the seed used in the random number generator.
*/
void
countnegative_initSeed(void) {
countnegative_seed = 0;
}
/*
Generates random integers between 0 and 8094
*/
int
countnegative_randomInteger(void) {
countnegative_seed = ((countnegative_seed * 133) + 81) % 8095;
return countnegative_seed;
}
/*
Initializes the given array with random integers.
*/
void
countnegative_initialize(matrix Array) {
register int OuterIndex, InnerIndex;
__pragma_loopbound(20, 20);
for (OuterIndex = 0; OuterIndex < MAXSIZE; OuterIndex++)
__pragma_loopbound(20, 20);
for (InnerIndex = 0; InnerIndex < MAXSIZE; InnerIndex++)
Array[OuterIndex][InnerIndex] = countnegative_randomInteger();
}
void
countnegative_init(void) {
countnegative_initSeed();
countnegative_initialize(countnegative_array);
}
int
countnegative_return(void) {
int checksum = (countnegative_postotal + countnegative_poscnt +
countnegative_negtotal + countnegative_negcnt);
return ((checksum == (int) 0x1778de) ? 0 : -1);
}
void
countnegative_sum(matrix Array) {
register int Outer, Inner;
int Ptotal = 0; /* changed these to locals in order to drive worst case */
int Ntotal = 0;
int Pcnt = 0;
int Ncnt = 0;
__pragma_loopbound(20, 20);
for (Outer = 0; Outer < MAXSIZE; Outer++)
_Pragma(
"loopbound min 20 max 20") for (Inner = 0; Inner < MAXSIZE;
Inner++) if (Array[Outer][Inner] >=
0) {
Ptotal += Array[Outer][Inner];
Pcnt++;
}
else {
Ntotal += Array[Outer][Inner];
Ncnt++;
}
countnegative_postotal = Ptotal;
countnegative_poscnt = Pcnt;
countnegative_negtotal = Ntotal;
countnegative_negcnt = Ncnt;
}
/*
The main function
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
countnegative_main(void) {
countnegative_sum(countnegative_array);
}
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
countnegative_init();
countnegative_main();
return (countnegative_return());
}

View File

@ -0,0 +1,157 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 2.0
Name: countnegative
Author: unknown
Function: Counts negative and non-negative numbers in a
matrix. Features nested loops, well-structured code.
Source: MRTC
http://www.mrtc.mdh.se/projects/wcet/wcet_bench/cnt/cnt.c
Changes: Changed split between initialization and computation
License: May be used, modified, and re-distributed freely
*/
/*
The dimension of the matrix
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
#define MAXSIZE 20
/*
Type definition for the matrix
*/
typedef int matrix[MAXSIZE][MAXSIZE];
/*
Forward declaration of functions
*/
__attribute__((always_inline)) static inline void countnegative_initSeed(void);
__attribute__((always_inline)) static inline int
countnegative_randomInteger(void);
__attribute__((always_inline)) static inline void
countnegative_initialize(matrix);
__attribute__((always_inline)) static inline void countnegative_init(void);
__attribute__((always_inline)) static inline int countnegative_return(void);
__attribute__((always_inline)) static inline void countnegative_sum(matrix);
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
countnegative_main(void);
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void);
/*
Globals
*/
volatile int countnegative_seed;
matrix countnegative_array;
int countnegative_postotal, countnegative_negtotal;
int countnegative_poscnt, countnegative_negcnt;
/*
Initializes the seed used in the random number generator.
*/
__attribute__((always_inline)) static inline void
countnegative_initSeed(void) {
countnegative_seed = 0;
}
/*
Generates random integers between 0 and 8094
*/
__attribute__((always_inline)) static inline int
countnegative_randomInteger(void) {
countnegative_seed = ((countnegative_seed * 133) + 81) % 8095;
return countnegative_seed;
}
/*
Initializes the given array with random integers.
*/
__attribute__((always_inline)) static inline void
countnegative_initialize(matrix Array) {
register int OuterIndex, InnerIndex;
__pragma_loopbound(20, 20);
for (OuterIndex = 0; OuterIndex < MAXSIZE; OuterIndex++)
__pragma_loopbound(20, 20);
for (InnerIndex = 0; InnerIndex < MAXSIZE; InnerIndex++)
Array[OuterIndex][InnerIndex] = countnegative_randomInteger();
}
__attribute__((always_inline)) static inline void
countnegative_init(void) {
countnegative_initSeed();
countnegative_initialize(countnegative_array);
}
__attribute__((always_inline)) static inline int
countnegative_return(void) {
int checksum = (countnegative_postotal + countnegative_poscnt +
countnegative_negtotal + countnegative_negcnt);
return ((checksum == (int) 0x1778de) ? 0 : -1);
}
__attribute__((always_inline)) static inline void
countnegative_sum(matrix Array) {
register int Outer, Inner;
int Ptotal = 0; /* changed these to locals in order to drive worst case */
int Ntotal = 0;
int Pcnt = 0;
int Ncnt = 0;
__pragma_loopbound(20, 20);
for (Outer = 0; Outer < MAXSIZE; Outer++)
_Pragma(
"loopbound min 20 max 20") for (Inner = 0; Inner < MAXSIZE;
Inner++) if (Array[Outer][Inner] >=
0) {
Ptotal += Array[Outer][Inner];
Pcnt++;
}
else {
Ntotal += Array[Outer][Inner];
Ncnt++;
}
countnegative_postotal = Ptotal;
countnegative_poscnt = Pcnt;
countnegative_negtotal = Ntotal;
countnegative_negcnt = Ncnt;
}
/*
The main function
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
countnegative_main(void) {
countnegative_sum(countnegative_array);
}
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
countnegative_init();
countnegative_main();
return (countnegative_return());
}

View File

@ -0,0 +1,26 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(cubic)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/cubic.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/cubic.c"
"generated/modified_sources/default/wcclibm.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,78 @@
Original provenience: MiBench benchmark suite,
http://wwweb.eecs.umich.edu/mibench
2016-02-09:
- Added TACLeBench header
- Renamed benchmark from 'basicmath_small' to 'basicmath'
- Fixed a typo in code comments: 'soem' -> 'some'
- Removed unused variable 'n' from the main funcion
- Added variable 'double Y' to the main function and accumulated the results of
'deg2rad(X)' and 'rad2deg(X)' in this variable so that the compiler warning
'statement with no effect' is fixed.
- Removed conditionally compiled main (test) function from isqrt.c
- Removed conditionally compiled main (test) function from cubic.c
- Removed commented-out code
- Removed unused function, variable, macro and type declarations, structs and
unions
- Removed seemingly unnecessary empty lines
- Renamed memcpy.t to basicmath_libc.c
- Removed unused files:
rad2deg.c
sniptype.h
sniptype.h
- Created basicmath_libc.h and put declaration of basicmath_memcpy() in it
- Reorganized snipmath.h so that the following are in the given order just
after the header
- includes
- declarations of functions
- Reorganized sniptype.h so that the following are in the given order just
after the header
- macro definitions
- type definitions
- Removed duplicated copyright information from wcclibm.c
- Removed __STDC__ checks from wcclibm.c and used only ANSI style function
arguments
- Removed 'last modified' comments from files
- Removed mention 'use __kernel_rem_pio2f()' from comments of function
__ieee754_rem_pio2f() since it doesn't really use it.
- Removed math functions specialization macros from wcclibm.h and updated call
sites with explicit nameks of the functions.
- Removed '#define double float' from wcclibm.h and replaced all 'double's
with 'float's in the benchmark
- Added a new main function that calls the old main function
- Annotated basicmath_main() as the entry point of the analysis
- Applied code formatting according to the following rules
- Lines shall not be wider than 80 characters; whenever possible, appropriate
line breaks shall be inserted to keep lines below 80 characters
- Indentation is done using whitespaces only, no tabs. Code is indented by
two whitespaces
- Two empty lines are put between any two functions
- In non-empty lists or index expressions, opening '(' and '[' are followed by
one whitespace, closing ')' and ']' are preceded by one whitespace
- In comma- or colon-separated argument lists, one whitespace is put after
each comma/colon
- Names of functions and global variables all start with a benchmark-specific
prefix (here: statemate_) followed by lowercase letter
- For pointer types, one whitespace is put before the '*'
- Operators within expressions shall be preceded and followed by one
whitespace
- Code of then- and else-parts of if-then-else statements shall be put in
separate lines, not in the same lines as the if-condition or the keyword
"else"
- Opening braces '{' denoting the beginning of code for some if-else or loop
body shall be put at the end of the same line where the keywords "if",
"else", "for", "while" etc. occur
2017-06-27
- Introduce basicmath_init and basicmath_return functions.
- Add prefix basicmath_ to global variables.
- Introduce dummy initialization in ieee754_rem_pio2f to please linter.
2017-07-10
- Fix possible stack buffer overflow caused by sizeof of incorrect type.
2019-03-07
-split basicmath into seperate files
-Add TACLeBench Header
-put each benchmark into a seperate folder
-adjust the code formatting to the common TACLeBench code style

View File

@ -0,0 +1,156 @@
/*
** CUBIC.C - Solve a cubic polynomial
** public domain by Ross Cottrell
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: cubic
Author: Ross Cottrell
Function: cubic solves some cubic functions
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
#include "wcclibm.h"
#include "snipmath.h"
/*
Forward declaration of functions
*/
void cubic_solveCubic( float a, float b, float c, float d,
int *solutions, float *x );
void cubic_main( void );
void cubic_init( void );
int cubic_return( void );
int main( void );
/*
Declaration of global variables
*/
float cubic_a1, cubic_b1, cubic_c1, cubic_d1;
float cubic_a2, cubic_b2, cubic_c2, cubic_d2;
float cubic_a3, cubic_b3, cubic_c3, cubic_d3;
float cubic_a4, cubic_b4, cubic_c4, cubic_d4;
float cubic_x[3];
float cubic_X, cubic_Y;
int cubic_solutions;
int cubic_checksum;
/*
Initialization function
*/
void cubic_init( void )
{
cubic_a1 = 1.0f, cubic_b1 = -10.5f, cubic_c1 = 32.0f, cubic_d1 = -30.0f;
cubic_a2 = 1.0f, cubic_b2 = -4.5f, cubic_c2 = 17.0f, cubic_d2 = -30.0f;
cubic_a3 = 1.0f, cubic_b3 = -3.5f, cubic_c3 = 22.0f, cubic_d3 = -31.0f;
cubic_a4 = 1.0f, cubic_b4 = -13.7f, cubic_c4 = 1.0f, cubic_d4 = -35.0f;
cubic_X = 0, cubic_Y = 0;
cubic_checksum = 0;
}
/*
Return function
*/
int cubic_return( void )
{
if ( cubic_checksum == 1051 )
return 0;
else
return -1;
}
/*
Main functions
*/
void _Pragma( "entrypoint" ) cubic_main( void )
{
/* solve some cubic functions */
/* should get 3 solutions: 2, 6 & 2.5 */
cubic_solveCubic( cubic_a1, cubic_b1, cubic_c1, cubic_d1, &cubic_solutions, cubic_x );
cubic_checksum += cubic_solutions;
cubic_solveCubic( cubic_a2, cubic_b2, cubic_c2, cubic_d2, &cubic_solutions, cubic_x );
cubic_checksum += cubic_solutions;
cubic_solveCubic( cubic_a3, cubic_b3, cubic_c3, cubic_d3, &cubic_solutions, cubic_x );
cubic_checksum += cubic_solutions;
cubic_solveCubic( cubic_a4, cubic_b4, cubic_c4, cubic_d4, &cubic_solutions, cubic_x );
cubic_checksum += cubic_solutions;
/* Now solve some random equations */
_Pragma( "loopbound min 5 max 5" )
for ( cubic_a1 = 1; cubic_a1 < 10; cubic_a1 += 2 ) {
_Pragma( "loopbound min 5 max 5" )
for ( cubic_b1 = 10; cubic_b1 > 0; cubic_b1 -= 2 ) {
_Pragma( "loopbound min 7 max 7" )
for ( cubic_c1 = 5; cubic_c1 < 15; cubic_c1 += 1.5f ) {
_Pragma( "loopbound min 5 max 5" )
for ( cubic_d1 = -1; cubic_d1 > -11; cubic_d1 -= 2 ) {
cubic_solveCubic( cubic_a1, cubic_b1, cubic_c1, cubic_d1, &cubic_solutions, cubic_x );
cubic_checksum += cubic_solutions;
}
}
}
}
}
void cubic_solveCubic( float a, float b, float c, float d,
int *solutions, float *x )
{
float a1 = b / a, a2 = c / a, a3 = d / a;
float Q = ( a1 * a1 - 3.0f * a2 ) / 9.0f;
float R = ( 2.0f * a1 * a1 * a1 - 9.0f * a1 * a2 + 27.0f * a3 ) / 54.0f;
float R2_Q3 = R * R - Q * Q * Q;
float theta;
if ( R2_Q3 <= 0 ) {
*solutions = 3;
theta = basicmath___ieee754_acosf( R / basicmath___ieee754_sqrtf( Q * Q * Q ) );
x[0] = -2.0f * basicmath___ieee754_sqrtf( Q ) * basicmath___cosf(
theta / 3.0f ) - a1 / 3.0f;
x[1] = -2.0f * basicmath___ieee754_sqrtf( Q ) * basicmath___cosf( (
theta + 2.0f * PI ) / 3.0f ) - a1 / 3.0f;
x[2] = -2.0f * basicmath___ieee754_sqrtf( Q ) * basicmath___cosf( (
theta + 4.0f * PI ) / 3.0f ) - a1 / 3.0f;
} else {
*solutions = 1;
x[0] = basicmath___ieee754_powf( basicmath___ieee754_sqrtf( R2_Q3 ) +
basicmath___fabsf( R ), 1 / 3.0f );
x[0] += Q / x[0];
x[0] *= ( R < 0.0f ) ? 1 : -1;
x[0] -= a1 / 3.0f;
}
}
int main( void )
{
cubic_init();
cubic_main();
return cubic_return();
}

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,162 @@
/*
** CUBIC.C - Solve a cubic polynomial
** public domain by Ross Cottrell
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: cubic
Author: Ross Cottrell
Function: cubic solves some cubic functions
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
#include "snipmath.h"
#include "wcclibm.h"
/*
Forward declaration of functions
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
void cubic_solveCubic(float a, float b, float c, float d, int *solutions,
float *x);
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
cubic_main(void);
void cubic_init(void);
int cubic_return(void);
__attribute__((noinline)) __attribute__((export_name("main"))) int main(void);
/*
Declaration of global variables
*/
float cubic_a1, cubic_b1, cubic_c1, cubic_d1;
float cubic_a2, cubic_b2, cubic_c2, cubic_d2;
float cubic_a3, cubic_b3, cubic_c3, cubic_d3;
float cubic_a4, cubic_b4, cubic_c4, cubic_d4;
float cubic_x[3];
float cubic_X, cubic_Y;
int cubic_solutions;
int cubic_checksum;
/*
Initialization function
*/
void
cubic_init(void) {
cubic_a1 = 1.0f, cubic_b1 = -10.5f, cubic_c1 = 32.0f, cubic_d1 = -30.0f;
cubic_a2 = 1.0f, cubic_b2 = -4.5f, cubic_c2 = 17.0f, cubic_d2 = -30.0f;
cubic_a3 = 1.0f, cubic_b3 = -3.5f, cubic_c3 = 22.0f, cubic_d3 = -31.0f;
cubic_a4 = 1.0f, cubic_b4 = -13.7f, cubic_c4 = 1.0f, cubic_d4 = -35.0f;
cubic_X = 0, cubic_Y = 0;
cubic_checksum = 0;
}
/*
Return function
*/
int
cubic_return(void) {
if (cubic_checksum == 1051)
return 0;
else
return -1;
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
cubic_main(void) {
/* solve some cubic functions */
/* should get 3 solutions: 2, 6 & 2.5 */
cubic_solveCubic(cubic_a1, cubic_b1, cubic_c1, cubic_d1, &cubic_solutions,
cubic_x);
cubic_checksum += cubic_solutions;
cubic_solveCubic(cubic_a2, cubic_b2, cubic_c2, cubic_d2, &cubic_solutions,
cubic_x);
cubic_checksum += cubic_solutions;
cubic_solveCubic(cubic_a3, cubic_b3, cubic_c3, cubic_d3, &cubic_solutions,
cubic_x);
cubic_checksum += cubic_solutions;
cubic_solveCubic(cubic_a4, cubic_b4, cubic_c4, cubic_d4, &cubic_solutions,
cubic_x);
cubic_checksum += cubic_solutions;
/* Now solve some random equations */
__pragma_loopbound(5, 5);
for (cubic_a1 = 1; cubic_a1 < 10; cubic_a1 += 2) {
__pragma_loopbound(5, 5);
for (cubic_b1 = 10; cubic_b1 > 0; cubic_b1 -= 2) {
__pragma_loopbound(7, 7);
for (cubic_c1 = 5; cubic_c1 < 15; cubic_c1 += 1.5f) {
__pragma_loopbound(5, 5);
for (cubic_d1 = -1; cubic_d1 > -11; cubic_d1 -= 2) {
cubic_solveCubic(cubic_a1, cubic_b1, cubic_c1, cubic_d1,
&cubic_solutions, cubic_x);
cubic_checksum += cubic_solutions;
}
}
}
}
}
void
cubic_solveCubic(float a, float b, float c, float d, int *solutions, float *x) {
float a1 = b / a, a2 = c / a, a3 = d / a;
float Q = (a1 * a1 - 3.0f * a2) / 9.0f;
float R = (2.0f * a1 * a1 * a1 - 9.0f * a1 * a2 + 27.0f * a3) / 54.0f;
float R2_Q3 = R * R - Q * Q * Q;
float theta;
if (R2_Q3 <= 0) {
*solutions = 3;
theta =
basicmath___ieee754_acosf(R / basicmath___ieee754_sqrtf(Q * Q * Q));
x[0] = -2.0f * basicmath___ieee754_sqrtf(Q) *
basicmath___cosf(theta / 3.0f) -
a1 / 3.0f;
x[1] = -2.0f * basicmath___ieee754_sqrtf(Q) *
basicmath___cosf((theta + 2.0f * PI) / 3.0f) -
a1 / 3.0f;
x[2] = -2.0f * basicmath___ieee754_sqrtf(Q) *
basicmath___cosf((theta + 4.0f * PI) / 3.0f) -
a1 / 3.0f;
} else {
*solutions = 1;
x[0] = basicmath___ieee754_powf(
basicmath___ieee754_sqrtf(R2_Q3) + basicmath___fabsf(R), 1 / 3.0f);
x[0] += Q / x[0];
x[0] *= (R < 0.0f) ? 1 : -1;
x[0] -= a1 / 3.0f;
}
}
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
cubic_init();
cubic_main();
return cubic_return();
}

View File

@ -0,0 +1,67 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
from: @(#)fdlibm.h 5.1 93/09/24
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: math_private.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: fdlibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _MATH_PRIVATE_H_
#define _MATH_PRIVATE_H_
#include "wcclibm.h"
/* A union which permits us to convert between a float and a 32 bit int. */
typedef union {
float value;
u_int32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i, d) \
{ \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
}
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d, i) \
{ \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
}
#endif /* _MATH_PRIVATE_H_ */

View File

@ -0,0 +1,30 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: pi
Author: unknown
Function: Header file for definition of pi
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
#ifndef PI__H
#define PI__H
#ifndef PI
#define PI 3.14f
#endif
#endif /* PI__H */

View File

@ -0,0 +1,37 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: snipmath
Author: unknown
Function: Header file for SNIPPETS math functions and macros
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
/*
SNIPMATH.H - Header file for SNIPPETS math functions and macros
*/
#ifndef SNIPMATH__H
#define SNIPMATH__H
#include "pi.h"
#include "wcclibm.h"
struct int_sqrt {
unsigned short sqrt, frac;
};
#endif /* SNIPMATH__H */

View File

@ -0,0 +1,796 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.c
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.c
Changes: No major functional changes.
License: See the terms above.
*/
#include "wcclibm.h"
#include "math_private.h"
/* e_acosf.c -- float version of e_acos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
static const float basicmath_pi = 3.1415925026e+00f, /* 0x40490fda */
basicmath_pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */
basicmath_pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */
basicmath_pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_pS1 = -3.2556581497e-01f, /* 0xbea6b090 */
basicmath_pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */
basicmath_pS3 = -4.0055535734e-02f, /* 0xbd241146 */
basicmath_pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */
basicmath_pS5 = 3.4793309169e-05f, /* 0x3811ef08 */
basicmath_qS1 = -2.4033949375e+00f, /* 0xc019d139 */
basicmath_qS2 = 2.0209457874e+00f, /* 0x4001572d */
basicmath_qS3 = -6.8828397989e-01f, /* 0xbf303361 */
basicmath_qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */
float
basicmath___ieee754_acosf(float x) {
float z, p, q, r, w, s, c, df;
int32_t hx, ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix == 0x3f800000) { /* |x|==1 */
if (hx > 0)
return 0.0f; /* acos(1) = 0 */
else
return basicmath_pi +
(float) 2.0f * basicmath_pio2_lo; /* acos(-1)= pi */
} else if (ix > 0x3f800000) { /* |x| >= 1 */
return (x - x) / (x - x); /* acos(|x|>1) is NaN */
}
if (ix < 0x3f000000) { /* |x| < 0.5 */
if (ix <= 0x23000000)
return basicmath_pio2_hi + basicmath_pio2_lo; /*if|x|<2**-57*/
z = x * x;
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
r = p / q;
return basicmath_pio2_hi - (x - (basicmath_pio2_lo - x * r));
} else if (hx < 0) { /* x < -0.5 */
z = (basicmath_one + x) * (float) 0.5f;
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
s = basicmath___ieee754_sqrtf(z);
r = p / q;
w = r * s - basicmath_pio2_lo;
return basicmath_pi - (float) 2.0f * (s + w);
} else { /* x > 0.5 */
int32_t idf;
z = (basicmath_one - x) * (float) 0.5f;
s = basicmath___ieee754_sqrtf(z);
df = s;
GET_FLOAT_WORD(idf, df);
SET_FLOAT_WORD(df, idf & 0xfffff000);
c = (z - df * df) / (s + df);
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
r = p / q;
w = r * s + c;
return (float) 2.0f * (df + w);
}
}
/* e_powf.c -- float version of e_pow.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_bp[] =
{
1.0f,
1.5f,
},
basicmath_dp_h[] =
{
0.0f,
5.84960938e-01f,
}, /* 0x3f15c000 */
basicmath_dp_l[] =
{
0.0f,
1.56322085e-06f,
}, /* 0x35d1cfdc */
/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
basicmath_L1 = 6.0000002384e-01f, /* 0x3f19999a */
basicmath_L2 = 4.2857143283e-01f, /* 0x3edb6db7 */
basicmath_L3 = 3.3333334327e-01f, /* 0x3eaaaaab */
basicmath_L4 = 2.7272811532e-01f, /* 0x3e8ba305 */
basicmath_L5 = 2.3066075146e-01f, /* 0x3e6c3255 */
basicmath_L6 = 2.0697501302e-01f, /* 0x3e53f142 */
basicmath_P1 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_P2 = -2.7777778450e-03f, /* 0xbb360b61 */
basicmath_P3 = 6.6137559770e-05f, /* 0x388ab355 */
basicmath_P4 = -1.6533901999e-06f, /* 0xb5ddea0e */
basicmath_P5 = 4.1381369442e-08f, /* 0x3331bb4c */
basicmath_lg2 = 6.9314718246e-01f, /* 0x3f317218 */
basicmath_lg2_h = 6.93145752e-01f, /* 0x3f317200 */
basicmath_lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */
basicmath_ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */
basicmath_cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */
basicmath_cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */
basicmath_cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */
basicmath_ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */
basicmath_ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/
basicmath_ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/
float
basicmath___ieee754_powf(float x, float y) {
float z, ax, z_h, z_l, p_h, p_l;
float y1, t1, t2, r, s, t, u, v, w;
int32_t i, j, k, yisint, n;
int32_t hx, hy, ix, iy, is;
GET_FLOAT_WORD(hx, x);
GET_FLOAT_WORD(hy, y);
ix = hx & 0x7fffffff;
iy = hy & 0x7fffffff;
/* y==zero: x**0 = 1 */
if (iy == 0)
return basicmath_one;
/* x==+-1 */
if (x == 1.0f)
return basicmath_one;
if (x == -1.0f && basicmath___isinff(y))
return basicmath_one;
/* +-NaN return x+y */
if (ix > 0x7f800000 || iy > 0x7f800000)
return x + y;
/* determine if y is an odd int when x < 0
yisint = 0 ... y is not an integer
yisint = 1 ... y is an odd int
yisint = 2 ... y is an even int
*/
yisint = 0;
if (hx < 0) {
if (iy >= 0x4b800000)
yisint = 2; /* even integer y */
else if (iy >= 0x3f800000) {
k = (iy >> 23) - 0x7f; /* exponent */
j = iy >> (23 - k);
if ((j << (23 - k)) == iy)
yisint = 2 - (j & 1);
}
}
/* special value of y */
if (iy == 0x7f800000) { /* y is +-inf */
if (ix == 0x3f800000)
return y - y; /* inf**+-1 is NaN */
else if (ix > 0x3f800000) /* (|x|>1)**+-inf = inf,0 */
return (hy >= 0) ? y : basicmath_zero;
else /* (|x|<1)**-,+inf = inf,0 */
return (hy < 0) ? -y : basicmath_zero;
}
if (iy == 0x3f800000) { /* y is +-1 */
if (hy < 0)
return basicmath_one / x;
else
return x;
}
if (hy == 0x40000000)
return x * x; /* y is 2 */
if (hy == 0x3f000000) { /* y is 0.5 */
if (hx >= 0) /* x >= +0 */
return basicmath___ieee754_sqrtf(x);
}
ax = basicmath___fabsf(x);
/* special value of x */
if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) {
z = ax; /*x is +-0,+-inf,+-1*/
if (hy < 0)
z = basicmath_one / z; /* z = (1/|x|) */
if (hx < 0) {
if (((ix - 0x3f800000) | yisint) == 0) {
z = (z - z) / (z - z); /* (-1)**non-int is NaN */
} else if (yisint == 1)
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
/* (x<0)**(non-int) is NaN */
if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0)
return (x - x) / (x - x);
/* |y| is huge */
if (iy > 0x4d000000) { /* if |y| > 2**27 */
/* over/underflow if x is not close to one */
if (ix < 0x3f7ffff8)
return (hy < 0) ? basicmath_huge * basicmath_huge
: basicmath_tiny * basicmath_tiny;
if (ix > 0x3f800007)
return (hy > 0) ? basicmath_huge * basicmath_huge
: basicmath_tiny * basicmath_tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = x - 1; /* t has 20 trailing zeros */
w = (t * t) *
((float) 0.5f - t * ((float) 0.333333333333f - t * (float) 0.25f));
u = basicmath_ivln2_h * t; /* ivln2_h has 16 sig. bits */
v = t * basicmath_ivln2_l - w * basicmath_ivln2;
t1 = u + v;
GET_FLOAT_WORD(is, t1);
SET_FLOAT_WORD(t1, is & 0xfffff000);
t2 = v - (t1 - u);
} else {
float s2, s_h, s_l, t_h, t_l;
n = 0;
/* take care subnormal number */
if (ix < 0x00800000) {
ax *= basicmath_two24;
n -= 24;
GET_FLOAT_WORD(ix, ax);
}
n += ((ix) >> 23) - 0x7f;
j = ix & 0x007fffff;
/* determine interval */
ix = j | 0x3f800000; /* normalize ix */
if (j <= 0x1cc471)
k = 0; /* |x|<sqrt(3/2) */
else if (j < 0x5db3d7)
k = 1; /* |x|<sqrt(3) */
else {
k = 0;
n += 1;
ix -= 0x00800000;
}
SET_FLOAT_WORD(ax, ix);
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
u = ax - basicmath_bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
v = basicmath_one / (ax + basicmath_bp[k]);
s = u * v;
s_h = s;
GET_FLOAT_WORD(is, s_h);
SET_FLOAT_WORD(s_h, is & 0xfffff000);
/* t_h=ax+bp[k] High */
SET_FLOAT_WORD(t_h, ((ix >> 1) | 0x20000000) + 0x0040000 + (k << 21));
t_l = ax - (t_h - basicmath_bp[k]);
s_l = v * ((u - s_h * t_h) - s_h * t_l);
/* compute log(ax) */
s2 = s * s;
r = s2 * s2 *
(basicmath_L1 +
s2 * (basicmath_L2 +
s2 * (basicmath_L3 +
s2 * (basicmath_L4 +
s2 * (basicmath_L5 + s2 * basicmath_L6)))));
r += s_l * (s_h + s);
s2 = s_h * s_h;
t_h = (float) 3.0f + s2 + r;
GET_FLOAT_WORD(is, t_h);
SET_FLOAT_WORD(t_h, is & 0xfffff000);
t_l = r - ((t_h - (float) 3.0f) - s2);
/* u+v = s*(1+...) */
u = s_h * t_h;
v = s_l * t_h + t_l * s;
/* 2/(3log2)*(s+...) */
p_h = u + v;
GET_FLOAT_WORD(is, p_h);
SET_FLOAT_WORD(p_h, is & 0xfffff000);
p_l = v - (p_h - u);
z_h = basicmath_cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = basicmath_cp_l * p_h + p_l * basicmath_cp + basicmath_dp_l[k];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = (float) n;
t1 = (((z_h + z_l) + basicmath_dp_h[k]) + t);
GET_FLOAT_WORD(is, t1);
SET_FLOAT_WORD(t1, is & 0xfffff000);
t2 = z_l - (((t1 - t) - basicmath_dp_h[k]) - z_h);
}
s = basicmath_one; /* s (sign of result -ve**odd) = -1 else = 1 */
if (((((u_int32_t) hx >> 31) - 1) | (yisint - 1)) == 0)
s = -basicmath_one; /* (-ve)**(odd int) */
/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
GET_FLOAT_WORD(is, y);
SET_FLOAT_WORD(y1, is & 0xfffff000);
p_l = (y - y1) * t1 + y * t2;
p_h = y1 * t1;
z = p_l + p_h;
GET_FLOAT_WORD(j, z);
if (j > 0x43000000) /* if z > 128 */
return s * basicmath_huge * basicmath_huge; /* overflow */
else if (j == 0x43000000) { /* if z == 128 */
if (p_l + basicmath_ovt > z - p_h)
return s * basicmath_huge * basicmath_huge; /* overflow */
} else if ((j & 0x7fffffff) > 0x43160000) /* z <= -150 */
return s * basicmath_tiny * basicmath_tiny; /* underflow */
else if ((u_int32_t) j == 0xc3160000) { /* z == -150 */
if (p_l <= z - p_h)
return s * basicmath_tiny * basicmath_tiny; /* underflow */
}
/*
compute 2**(p_h+p_l)
*/
i = j & 0x7fffffff;
k = (i >> 23) - 0x7f;
n = 0;
if (i > 0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
n = j + (0x00800000 >> (k + 1));
k = ((n & 0x7fffffff) >> 23) - 0x7f; /* new k for n */
SET_FLOAT_WORD(t, n & ~(0x007fffff >> k));
n = ((n & 0x007fffff) | 0x00800000) >> (23 - k);
if (j < 0)
n = -n;
p_h -= t;
}
t = p_l + p_h;
GET_FLOAT_WORD(is, t);
SET_FLOAT_WORD(t, is & 0xfffff000);
u = t * basicmath_lg2_h;
v = (p_l - (t - p_h)) * basicmath_lg2 + t * basicmath_lg2_l;
z = u + v;
w = v - (z - u);
t = z * z;
t1 = z -
t * (basicmath_P1 +
t * (basicmath_P2 +
t * (basicmath_P3 + t * (basicmath_P4 + t * basicmath_P5))));
r = (z * t1) / (t1 - basicmath_two) - (w + z * w);
z = basicmath_one - (r - z);
GET_FLOAT_WORD(j, z);
j += (n << 23);
if ((j >> 23) <= 0)
z = basicmath___scalbnf(z, n); /* subnormal output */
else
SET_FLOAT_WORD(z, j);
return s * z;
}
/* e_rem_pio2f.c -- float version of e_rem_pio2.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/* basicmath___ieee754_rem_pio2f(x,y)
return the remainder of x rem pi/2 in y[0]+y[1]
*/
/* This array is like the one in e_rem_pio2.c, but the numbers are
single precision and the last 8 bits are forced to 0. */
static const int32_t basicmath_npio2_hw[] = {
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
0x4242c700, 0x42490f00};
/*
invpio2: 24 bits of 2/pi
pio2_1: first 17 bit of pi/2
pio2_1t: pi/2 - pio2_1
pio2_2: second 17 bit of pi/2
pio2_2t: pi/2 - (pio2_1+pio2_2)
pio2_3: third 17 bit of pi/2
pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const float basicmath_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
basicmath_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
basicmath_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
basicmath_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
basicmath_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
basicmath_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
basicmath_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
int32_t
basicmath___ieee754_rem_pio2f(float x, float *y) {
float z, w, t, r, fn;
int32_t i, j, n, ix, hx;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix <= 0x3f490fd8) { /* |x| ~<= pi/4 , no need for reduction */
y[0] = x;
y[1] = 0;
return 0;
}
if (ix < 0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
if (hx > 0) {
z = x - basicmath_pio2_1;
if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */
y[0] = z - basicmath_pio2_1t;
y[1] = (z - y[0]) - basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z -= basicmath_pio2_2;
y[0] = z - basicmath_pio2_2t;
y[1] = (z - y[0]) - basicmath_pio2_2t;
}
return 1;
} else { /* negative x */
z = x + basicmath_pio2_1;
if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */
y[0] = z + basicmath_pio2_1t;
y[1] = (z - y[0]) + basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z += basicmath_pio2_2;
y[0] = z + basicmath_pio2_2t;
y[1] = (z - y[0]) + basicmath_pio2_2t;
}
return -1;
}
}
if (ix <= 0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
t = basicmath___fabsf(x);
n = (int32_t) (t * basicmath_invpio2 + basicmath_half);
fn = (float) n;
r = t - fn * basicmath_pio2_1;
w = fn * basicmath_pio2_1t; /* 1st round good to 40 bit */
if (n < 32 &&
(int32_t) (ix & 0xffffff00) != basicmath_npio2_hw[n - 1]) {
y[0] = r - w; /* quick check no cancellation */
} else {
u_int32_t high;
j = ix >> 23;
y[0] = r - w;
GET_FLOAT_WORD(high, y[0]);
i = j - ((high >> 23) & 0xff);
if (i > 8) { /* 2nd iteration needed, good to 57 */
t = r;
w = fn * basicmath_pio2_2;
r = t - w;
w = fn * basicmath_pio2_2t - ((t - r) - w);
y[0] = r - w;
GET_FLOAT_WORD(high, y[0]);
i = j - ((high >> 23) & 0xff);
if (i > 25) { /* 3rd iteration need, 74 bits acc */
t = r; /* will cover all possible cases */
w = fn * basicmath_pio2_3;
r = t - w;
w = fn * basicmath_pio2_3t - ((t - r) - w);
y[0] = r - w;
}
}
}
y[1] = (r - y[0]) - w;
if (hx < 0) {
y[0] = -y[0];
y[1] = -y[1];
return -n;
} else
return n;
}
/*
all other (large) arguments
*/
if (ix >= 0x7f800000) { /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
// This will never happen in basicmath_small, because
// up to this point we have already returned a value
// for each of the possible inputs
y[0] = y[1] = x - x; /* dummy initialization */
return 0;
}
/* e_sqrtf.c -- float version of e_sqrt.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
float
basicmath___ieee754_sqrtf(float x) {
float z;
int32_t sign = (int) 0x80000000;
int32_t ix, s, q, m, t, i;
u_int32_t r;
GET_FLOAT_WORD(ix, x);
/* take care of Inf and NaN */
if ((ix & 0x7f800000) == 0x7f800000) {
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if (ix <= 0) {
if ((ix & (~sign)) == 0)
return x; /* sqrt(+-0) = +-0 */
else if (ix < 0)
return (x - x) / (x - x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix >> 23);
if (m == 0) { /* subnormal x */
__pragma_loopbound(0, 0);
for (i = 0; (ix & 0x00800000) == 0; i++)
ix <<= 1;
m -= i - 1;
}
m -= 127; /* unbias exponent */
ix = (ix & 0x007fffff) | 0x00800000;
if (m & 1) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
__pragma_loopbound(25, 25);
while (r != 0) {
t = s + r;
if (t <= ix) {
s = t + r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
/* use floating add to find out rounding direction */
if (ix != 0) {
z = basicmath_one - basicmath_tiny; /* trigger inexact flag */
if (z >= basicmath_one) {
z = basicmath_one + basicmath_tiny;
if (z > basicmath_one)
q += 2;
else
q += (q & 1);
}
}
ix = (q >> 1) + 0x3f000000;
ix += (m << 23);
SET_FLOAT_WORD(z, ix);
return z;
}
/* k_cosf.c -- float version of k_cos.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
basicmath_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
basicmath_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
basicmath_C4 = -2.7557314297e-07f, /* 0xb493f27c */
basicmath_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
basicmath_C6 = -1.1359647598e-11f; /* 0xad47d74e */
float
basicmath___kernel_cosf(float x, float y) {
float a, hz, z, r, qx;
int32_t ix;
GET_FLOAT_WORD(ix, x);
ix &= 0x7fffffff; /* ix = |x|'s high word*/
if (ix < 0x32000000) { /* if x < 2**27 */
if (((int) x) == 0)
return basicmath_one; /* generate inexact */
}
z = x * x;
r = z * (basicmath_C1 +
z * (basicmath_C2 +
z * (basicmath_C3 +
z * (basicmath_C4 +
z * (basicmath_C5 + z * basicmath_C6)))));
if (ix < 0x3e99999a) /* if |x| < 0.3 */
return basicmath_one - ((float) 0.5f * z - (z * r - x * y));
else {
if (ix > 0x3f480000) /* x > 0.78125 */
qx = (float) 0.28125f;
else {
SET_FLOAT_WORD(qx, ix - 0x01000000); /* x/4 */
}
hz = (float) 0.5f * z - qx;
a = basicmath_one - qx;
return a - (hz - (z * r - x * y));
}
}
/* k_sinf.c -- float version of k_sin.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
basicmath_S2 = 8.3333337680e-03f, /* 0x3c088889 */
basicmath_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
basicmath_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
basicmath_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
basicmath_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
float
basicmath___kernel_sinf(float x, float y, int iy) {
float z, r, v;
int32_t ix;
GET_FLOAT_WORD(ix, x);
ix &= 0x7fffffff; /* high word of x */
if (ix < 0x32000000) { /* |x| < 2**-27 */
if ((int) x == 0)
return x; /* generate inexact */
}
z = x * x;
v = z * x;
r = basicmath_S2 +
z * (basicmath_S3 +
z * (basicmath_S4 + z * (basicmath_S5 + z * basicmath_S6)));
if (iy == 0)
return x + v * (basicmath_S1 + z * r);
else
return x - ((z * (basicmath_half * y - v * r) - y) - v * basicmath_S1);
}
/* s_copysignf.c -- float version of s_copysign.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
copysignf(float x, float y)
copysignf(x,y) returns a value with the magnitude of x and
with the sign bit of y.
*/
float
basicmath___copysignf(float x, float y) {
u_int32_t ix, iy;
GET_FLOAT_WORD(ix, x);
GET_FLOAT_WORD(iy, y);
SET_FLOAT_WORD(x, (ix & 0x7fffffff) | (iy & 0x80000000));
return x;
}
/* s_cosf.c -- float version of s_cos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
float
basicmath___cosf(float x) {
float y[2], z = 0.0f;
int32_t n, ix;
GET_FLOAT_WORD(ix, x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if (ix <= 0x3f490fd8)
return basicmath___kernel_cosf(x, z);
/* cos(Inf or NaN) is NaN */
else if (ix >= 0x7f800000)
return x - x;
/* argument reduction needed */
else {
n = basicmath___ieee754_rem_pio2f(x, y);
switch (n & 3) {
case 0:
return basicmath___kernel_cosf(y[0], y[1]);
case 1:
return -basicmath___kernel_sinf(y[0], y[1], 1);
case 2:
return -basicmath___kernel_cosf(y[0], y[1]);
default:
return basicmath___kernel_sinf(y[0], y[1], 1);
}
}
}
/* s_fabsf.c -- float version of s_fabs.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
fabsf(x) returns the absolute value of x.
*/
float
basicmath___fabsf(float x) {
u_int32_t ix;
GET_FLOAT_WORD(ix, x);
SET_FLOAT_WORD(x, ix & 0x7fffffff);
return x;
}
/*
isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
no branching!
*/
int
basicmath___isinff(float x) {
int32_t ix, t;
GET_FLOAT_WORD(ix, x);
t = ix & 0x7fffffff;
t ^= 0x7f800000;
t |= -t;
return ~(t >> 31) & (ix >> 30);
}
/* s_scalbnf.c -- float version of s_scalbn.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_two25 = 3.355443200e+07f, /* 0x4c000000 */
basicmath_twom25 = 2.9802322388e-08f; /* 0x33000000 */
float
basicmath___scalbnf(float x, int n) {
int32_t k, ix;
GET_FLOAT_WORD(ix, x);
k = (ix & 0x7f800000) >> 23; /* extract exponent */
if (k == 0) { /* 0 or subnormal x */
if ((ix & 0x7fffffff) == 0)
return x; /* +-0 */
x *= basicmath_two25;
GET_FLOAT_WORD(ix, x);
k = ((ix & 0x7f800000) >> 23) - 25;
}
if (k == 0xff)
return x + x; /* NaN or Inf */
k = k + n;
if (n > 50000 || k > 0xfe)
return basicmath_huge *
basicmath___copysignf(basicmath_huge, x); /* overflow */
if (n < -50000)
return basicmath_tiny *
basicmath___copysignf(basicmath_tiny, x); /*underflow*/
if (k > 0) { /* normal result */
SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
return x;
}
if (k <= -25)
return basicmath_tiny *
basicmath___copysignf(basicmath_tiny, x); /*underflow*/
k += 25; /* subnormal result */
SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
return x * basicmath_twom25;
}

View File

@ -0,0 +1,58 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _WCCLIBM
#define _WCCLIBM
#define int32_t int
#define u_int32_t unsigned int
// Often used variables/consts
static const float basicmath_one = 1.0f, basicmath_tiny = 1.0e-30f,
basicmath_half = 5.0000000000e-01, /* 0x3f000000 */
basicmath_huge = 1.0e30, basicmath_two = 2.0,
basicmath_two24 = 16777216.0, /* 0x4b800000 */
basicmath_zero = 0.0;
float basicmath___copysignf(float x, float y);
float basicmath___cosf(float x);
float basicmath___fabsf(float x);
float basicmath___ieee754_acosf(float x);
float basicmath___ieee754_powf(float x, float y);
int32_t basicmath___ieee754_rem_pio2f(float x, float *y);
float basicmath___ieee754_sqrtf(float x);
int basicmath___isinff(float x);
float basicmath___kernel_cosf(float x, float y);
float basicmath___kernel_sinf(float x, float y, int iy);
float basicmath___scalbnf(float x, int n);
#endif // _WCCLIBM

View File

@ -0,0 +1,171 @@
/*
** CUBIC.C - Solve a cubic polynomial
** public domain by Ross Cottrell
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: cubic
Author: Ross Cottrell
Function: cubic solves some cubic functions
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
#include "snipmath.h"
#include "wcclibm.h"
/*
Forward declaration of functions
*/
// Wasm loop bounds
#include "wcclibm.c"
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
__attribute__((always_inline)) static inline void
cubic_solveCubic(float a, float b, float c, float d, int *solutions, float *x);
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
cubic_main(void);
__attribute__((always_inline)) static inline void cubic_init(void);
__attribute__((always_inline)) static inline int cubic_return(void);
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void);
/*
Declaration of global variables
*/
float cubic_a1, cubic_b1, cubic_c1, cubic_d1;
float cubic_a2, cubic_b2, cubic_c2, cubic_d2;
float cubic_a3, cubic_b3, cubic_c3, cubic_d3;
float cubic_a4, cubic_b4, cubic_c4, cubic_d4;
float cubic_x[3];
float cubic_X, cubic_Y;
int cubic_solutions;
int cubic_checksum;
/*
Initialization function
*/
__attribute__((always_inline)) static inline void
cubic_init(void) {
cubic_a1 = 1.0f, cubic_b1 = -10.5f, cubic_c1 = 32.0f, cubic_d1 = -30.0f;
cubic_a2 = 1.0f, cubic_b2 = -4.5f, cubic_c2 = 17.0f, cubic_d2 = -30.0f;
cubic_a3 = 1.0f, cubic_b3 = -3.5f, cubic_c3 = 22.0f, cubic_d3 = -31.0f;
cubic_a4 = 1.0f, cubic_b4 = -13.7f, cubic_c4 = 1.0f, cubic_d4 = -35.0f;
cubic_X = 0, cubic_Y = 0;
cubic_checksum = 0;
}
/*
Return function
*/
__attribute__((always_inline)) static inline int
cubic_return(void) {
if (cubic_checksum == 1051)
return 0;
else
return -1;
}
/*
Main functions
*/
__attribute__((noinline)) __attribute__((export_name("entrypoint")))
__attribute__((noinline)) __attribute__((export_name("entrypoint"))) void
cubic_main(void) {
/* solve some cubic functions */
/* should get 3 solutions: 2, 6 & 2.5 */
cubic_solveCubic(cubic_a1, cubic_b1, cubic_c1, cubic_d1, &cubic_solutions,
cubic_x);
cubic_checksum += cubic_solutions;
cubic_solveCubic(cubic_a2, cubic_b2, cubic_c2, cubic_d2, &cubic_solutions,
cubic_x);
cubic_checksum += cubic_solutions;
cubic_solveCubic(cubic_a3, cubic_b3, cubic_c3, cubic_d3, &cubic_solutions,
cubic_x);
cubic_checksum += cubic_solutions;
cubic_solveCubic(cubic_a4, cubic_b4, cubic_c4, cubic_d4, &cubic_solutions,
cubic_x);
cubic_checksum += cubic_solutions;
/* Now solve some random equations */
__pragma_loopbound(5, 5);
for (cubic_a1 = 1; cubic_a1 < 10; cubic_a1 += 2) {
__pragma_loopbound(5, 5);
for (cubic_b1 = 10; cubic_b1 > 0; cubic_b1 -= 2) {
__pragma_loopbound(7, 7);
for (cubic_c1 = 5; cubic_c1 < 15; cubic_c1 += 1.5f) {
__pragma_loopbound(5, 5);
for (cubic_d1 = -1; cubic_d1 > -11; cubic_d1 -= 2) {
cubic_solveCubic(cubic_a1, cubic_b1, cubic_c1, cubic_d1,
&cubic_solutions, cubic_x);
cubic_checksum += cubic_solutions;
}
}
}
}
}
__attribute__((always_inline)) static inline void
cubic_solveCubic(float a, float b, float c, float d, int *solutions, float *x) {
float a1 = b / a, a2 = c / a, a3 = d / a;
float Q = (a1 * a1 - 3.0f * a2) / 9.0f;
float R = (2.0f * a1 * a1 * a1 - 9.0f * a1 * a2 + 27.0f * a3) / 54.0f;
float R2_Q3 = R * R - Q * Q * Q;
float theta;
if (R2_Q3 <= 0) {
*solutions = 3;
theta =
basicmath___ieee754_acosf(R / basicmath___ieee754_sqrtf(Q * Q * Q));
x[0] = -2.0f * basicmath___ieee754_sqrtf(Q) *
basicmath___cosf(theta / 3.0f) -
a1 / 3.0f;
x[1] = -2.0f * basicmath___ieee754_sqrtf(Q) *
basicmath___cosf((theta + 2.0f * PI) / 3.0f) -
a1 / 3.0f;
x[2] = -2.0f * basicmath___ieee754_sqrtf(Q) *
basicmath___cosf((theta + 4.0f * PI) / 3.0f) -
a1 / 3.0f;
} else {
*solutions = 1;
x[0] = basicmath___ieee754_powf(
basicmath___ieee754_sqrtf(R2_Q3) + basicmath___fabsf(R), 1 / 3.0f);
x[0] += Q / x[0];
x[0] *= (R < 0.0f) ? 1 : -1;
x[0] -= a1 / 3.0f;
}
}
__attribute__((noinline)) __attribute__((export_name("main")))
__attribute__((noinline)) __attribute__((export_name("main"))) int
main(void) {
cubic_init();
cubic_main();
return cubic_return();
}

View File

@ -0,0 +1,67 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
from: @(#)fdlibm.h 5.1 93/09/24
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: math_private.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: fdlibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _MATH_PRIVATE_H_
#define _MATH_PRIVATE_H_
#include "wcclibm.h"
/* A union which permits us to convert between a float and a 32 bit int. */
typedef union {
float value;
u_int32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i, d) \
{ \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
}
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d, i) \
{ \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
}
#endif /* _MATH_PRIVATE_H_ */

View File

@ -0,0 +1,30 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: pi
Author: unknown
Function: Header file for definition of pi
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
#ifndef PI__H
#define PI__H
#ifndef PI
#define PI 3.14f
#endif
#endif /* PI__H */

View File

@ -0,0 +1,37 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: snipmath
Author: unknown
Function: Header file for SNIPPETS math functions and macros
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
/*
SNIPMATH.H - Header file for SNIPPETS math functions and macros
*/
#ifndef SNIPMATH__H
#define SNIPMATH__H
#include "pi.h"
#include "wcclibm.h"
struct int_sqrt {
unsigned short sqrt, frac;
};
#endif /* SNIPMATH__H */

View File

@ -0,0 +1,796 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.c
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.c
Changes: No major functional changes.
License: See the terms above.
*/
#include "wcclibm.h"
#include "math_private.h"
/* e_acosf.c -- float version of e_acos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
// Wasm loop bounds
__attribute__((import_module("__pragma"), import_name("loopbound"))) extern void
__pragma_loopbound(unsigned int min_bound, unsigned int max_bound);
static const float basicmath_pi = 3.1415925026e+00f, /* 0x40490fda */
basicmath_pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */
basicmath_pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */
basicmath_pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_pS1 = -3.2556581497e-01f, /* 0xbea6b090 */
basicmath_pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */
basicmath_pS3 = -4.0055535734e-02f, /* 0xbd241146 */
basicmath_pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */
basicmath_pS5 = 3.4793309169e-05f, /* 0x3811ef08 */
basicmath_qS1 = -2.4033949375e+00f, /* 0xc019d139 */
basicmath_qS2 = 2.0209457874e+00f, /* 0x4001572d */
basicmath_qS3 = -6.8828397989e-01f, /* 0xbf303361 */
basicmath_qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */
__attribute__((always_inline)) static inline float
basicmath___ieee754_acosf(float x) {
float z, p, q, r, w, s, c, df;
int32_t hx, ix;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix == 0x3f800000) { /* |x|==1 */
if (hx > 0)
return 0.0f; /* acos(1) = 0 */
else
return basicmath_pi +
(float) 2.0f * basicmath_pio2_lo; /* acos(-1)= pi */
} else if (ix > 0x3f800000) { /* |x| >= 1 */
return (x - x) / (x - x); /* acos(|x|>1) is NaN */
}
if (ix < 0x3f000000) { /* |x| < 0.5 */
if (ix <= 0x23000000)
return basicmath_pio2_hi + basicmath_pio2_lo; /*if|x|<2**-57*/
z = x * x;
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
r = p / q;
return basicmath_pio2_hi - (x - (basicmath_pio2_lo - x * r));
} else if (hx < 0) { /* x < -0.5 */
z = (basicmath_one + x) * (float) 0.5f;
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
s = basicmath___ieee754_sqrtf(z);
r = p / q;
w = r * s - basicmath_pio2_lo;
return basicmath_pi - (float) 2.0f * (s + w);
} else { /* x > 0.5 */
int32_t idf;
z = (basicmath_one - x) * (float) 0.5f;
s = basicmath___ieee754_sqrtf(z);
df = s;
GET_FLOAT_WORD(idf, df);
SET_FLOAT_WORD(df, idf & 0xfffff000);
c = (z - df * df) / (s + df);
p = z * (basicmath_pS0 +
z * (basicmath_pS1 +
z * (basicmath_pS2 +
z * (basicmath_pS3 +
z * (basicmath_pS4 + z * basicmath_pS5)))));
q = basicmath_one +
z * (basicmath_qS1 +
z * (basicmath_qS2 + z * (basicmath_qS3 + z * basicmath_qS4)));
r = p / q;
w = r * s + c;
return (float) 2.0f * (df + w);
}
}
/* e_powf.c -- float version of e_pow.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_bp[] =
{
1.0f,
1.5f,
},
basicmath_dp_h[] =
{
0.0f,
5.84960938e-01f,
}, /* 0x3f15c000 */
basicmath_dp_l[] =
{
0.0f,
1.56322085e-06f,
}, /* 0x35d1cfdc */
/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
basicmath_L1 = 6.0000002384e-01f, /* 0x3f19999a */
basicmath_L2 = 4.2857143283e-01f, /* 0x3edb6db7 */
basicmath_L3 = 3.3333334327e-01f, /* 0x3eaaaaab */
basicmath_L4 = 2.7272811532e-01f, /* 0x3e8ba305 */
basicmath_L5 = 2.3066075146e-01f, /* 0x3e6c3255 */
basicmath_L6 = 2.0697501302e-01f, /* 0x3e53f142 */
basicmath_P1 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_P2 = -2.7777778450e-03f, /* 0xbb360b61 */
basicmath_P3 = 6.6137559770e-05f, /* 0x388ab355 */
basicmath_P4 = -1.6533901999e-06f, /* 0xb5ddea0e */
basicmath_P5 = 4.1381369442e-08f, /* 0x3331bb4c */
basicmath_lg2 = 6.9314718246e-01f, /* 0x3f317218 */
basicmath_lg2_h = 6.93145752e-01f, /* 0x3f317200 */
basicmath_lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */
basicmath_ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */
basicmath_cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */
basicmath_cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */
basicmath_cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */
basicmath_ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */
basicmath_ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/
basicmath_ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/
__attribute__((always_inline)) static inline float
basicmath___ieee754_powf(float x, float y) {
float z, ax, z_h, z_l, p_h, p_l;
float y1, t1, t2, r, s, t, u, v, w;
int32_t i, j, k, yisint, n;
int32_t hx, hy, ix, iy, is;
GET_FLOAT_WORD(hx, x);
GET_FLOAT_WORD(hy, y);
ix = hx & 0x7fffffff;
iy = hy & 0x7fffffff;
/* y==zero: x**0 = 1 */
if (iy == 0)
return basicmath_one;
/* x==+-1 */
if (x == 1.0f)
return basicmath_one;
if (x == -1.0f && basicmath___isinff(y))
return basicmath_one;
/* +-NaN return x+y */
if (ix > 0x7f800000 || iy > 0x7f800000)
return x + y;
/* determine if y is an odd int when x < 0
yisint = 0 ... y is not an integer
yisint = 1 ... y is an odd int
yisint = 2 ... y is an even int
*/
yisint = 0;
if (hx < 0) {
if (iy >= 0x4b800000)
yisint = 2; /* even integer y */
else if (iy >= 0x3f800000) {
k = (iy >> 23) - 0x7f; /* exponent */
j = iy >> (23 - k);
if ((j << (23 - k)) == iy)
yisint = 2 - (j & 1);
}
}
/* special value of y */
if (iy == 0x7f800000) { /* y is +-inf */
if (ix == 0x3f800000)
return y - y; /* inf**+-1 is NaN */
else if (ix > 0x3f800000) /* (|x|>1)**+-inf = inf,0 */
return (hy >= 0) ? y : basicmath_zero;
else /* (|x|<1)**-,+inf = inf,0 */
return (hy < 0) ? -y : basicmath_zero;
}
if (iy == 0x3f800000) { /* y is +-1 */
if (hy < 0)
return basicmath_one / x;
else
return x;
}
if (hy == 0x40000000)
return x * x; /* y is 2 */
if (hy == 0x3f000000) { /* y is 0.5 */
if (hx >= 0) /* x >= +0 */
return basicmath___ieee754_sqrtf(x);
}
ax = basicmath___fabsf(x);
/* special value of x */
if (ix == 0x7f800000 || ix == 0 || ix == 0x3f800000) {
z = ax; /*x is +-0,+-inf,+-1*/
if (hy < 0)
z = basicmath_one / z; /* z = (1/|x|) */
if (hx < 0) {
if (((ix - 0x3f800000) | yisint) == 0) {
z = (z - z) / (z - z); /* (-1)**non-int is NaN */
} else if (yisint == 1)
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
/* (x<0)**(non-int) is NaN */
if (((((u_int32_t) hx >> 31) - 1) | yisint) == 0)
return (x - x) / (x - x);
/* |y| is huge */
if (iy > 0x4d000000) { /* if |y| > 2**27 */
/* over/underflow if x is not close to one */
if (ix < 0x3f7ffff8)
return (hy < 0) ? basicmath_huge * basicmath_huge
: basicmath_tiny * basicmath_tiny;
if (ix > 0x3f800007)
return (hy > 0) ? basicmath_huge * basicmath_huge
: basicmath_tiny * basicmath_tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = x - 1; /* t has 20 trailing zeros */
w = (t * t) *
((float) 0.5f - t * ((float) 0.333333333333f - t * (float) 0.25f));
u = basicmath_ivln2_h * t; /* ivln2_h has 16 sig. bits */
v = t * basicmath_ivln2_l - w * basicmath_ivln2;
t1 = u + v;
GET_FLOAT_WORD(is, t1);
SET_FLOAT_WORD(t1, is & 0xfffff000);
t2 = v - (t1 - u);
} else {
float s2, s_h, s_l, t_h, t_l;
n = 0;
/* take care subnormal number */
if (ix < 0x00800000) {
ax *= basicmath_two24;
n -= 24;
GET_FLOAT_WORD(ix, ax);
}
n += ((ix) >> 23) - 0x7f;
j = ix & 0x007fffff;
/* determine interval */
ix = j | 0x3f800000; /* normalize ix */
if (j <= 0x1cc471)
k = 0; /* |x|<sqrt(3/2) */
else if (j < 0x5db3d7)
k = 1; /* |x|<sqrt(3) */
else {
k = 0;
n += 1;
ix -= 0x00800000;
}
SET_FLOAT_WORD(ax, ix);
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
u = ax - basicmath_bp[k]; /* bp[0]=1.0, bp[1]=1.5 */
v = basicmath_one / (ax + basicmath_bp[k]);
s = u * v;
s_h = s;
GET_FLOAT_WORD(is, s_h);
SET_FLOAT_WORD(s_h, is & 0xfffff000);
/* t_h=ax+bp[k] High */
SET_FLOAT_WORD(t_h, ((ix >> 1) | 0x20000000) + 0x0040000 + (k << 21));
t_l = ax - (t_h - basicmath_bp[k]);
s_l = v * ((u - s_h * t_h) - s_h * t_l);
/* compute log(ax) */
s2 = s * s;
r = s2 * s2 *
(basicmath_L1 +
s2 * (basicmath_L2 +
s2 * (basicmath_L3 +
s2 * (basicmath_L4 +
s2 * (basicmath_L5 + s2 * basicmath_L6)))));
r += s_l * (s_h + s);
s2 = s_h * s_h;
t_h = (float) 3.0f + s2 + r;
GET_FLOAT_WORD(is, t_h);
SET_FLOAT_WORD(t_h, is & 0xfffff000);
t_l = r - ((t_h - (float) 3.0f) - s2);
/* u+v = s*(1+...) */
u = s_h * t_h;
v = s_l * t_h + t_l * s;
/* 2/(3log2)*(s+...) */
p_h = u + v;
GET_FLOAT_WORD(is, p_h);
SET_FLOAT_WORD(p_h, is & 0xfffff000);
p_l = v - (p_h - u);
z_h = basicmath_cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = basicmath_cp_l * p_h + p_l * basicmath_cp + basicmath_dp_l[k];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = (float) n;
t1 = (((z_h + z_l) + basicmath_dp_h[k]) + t);
GET_FLOAT_WORD(is, t1);
SET_FLOAT_WORD(t1, is & 0xfffff000);
t2 = z_l - (((t1 - t) - basicmath_dp_h[k]) - z_h);
}
s = basicmath_one; /* s (sign of result -ve**odd) = -1 else = 1 */
if (((((u_int32_t) hx >> 31) - 1) | (yisint - 1)) == 0)
s = -basicmath_one; /* (-ve)**(odd int) */
/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
GET_FLOAT_WORD(is, y);
SET_FLOAT_WORD(y1, is & 0xfffff000);
p_l = (y - y1) * t1 + y * t2;
p_h = y1 * t1;
z = p_l + p_h;
GET_FLOAT_WORD(j, z);
if (j > 0x43000000) /* if z > 128 */
return s * basicmath_huge * basicmath_huge; /* overflow */
else if (j == 0x43000000) { /* if z == 128 */
if (p_l + basicmath_ovt > z - p_h)
return s * basicmath_huge * basicmath_huge; /* overflow */
} else if ((j & 0x7fffffff) > 0x43160000) /* z <= -150 */
return s * basicmath_tiny * basicmath_tiny; /* underflow */
else if ((u_int32_t) j == 0xc3160000) { /* z == -150 */
if (p_l <= z - p_h)
return s * basicmath_tiny * basicmath_tiny; /* underflow */
}
/*
compute 2**(p_h+p_l)
*/
i = j & 0x7fffffff;
k = (i >> 23) - 0x7f;
n = 0;
if (i > 0x3f000000) { /* if |z| > 0.5, set n = [z+0.5] */
n = j + (0x00800000 >> (k + 1));
k = ((n & 0x7fffffff) >> 23) - 0x7f; /* new k for n */
SET_FLOAT_WORD(t, n & ~(0x007fffff >> k));
n = ((n & 0x007fffff) | 0x00800000) >> (23 - k);
if (j < 0)
n = -n;
p_h -= t;
}
t = p_l + p_h;
GET_FLOAT_WORD(is, t);
SET_FLOAT_WORD(t, is & 0xfffff000);
u = t * basicmath_lg2_h;
v = (p_l - (t - p_h)) * basicmath_lg2 + t * basicmath_lg2_l;
z = u + v;
w = v - (z - u);
t = z * z;
t1 = z -
t * (basicmath_P1 +
t * (basicmath_P2 +
t * (basicmath_P3 + t * (basicmath_P4 + t * basicmath_P5))));
r = (z * t1) / (t1 - basicmath_two) - (w + z * w);
z = basicmath_one - (r - z);
GET_FLOAT_WORD(j, z);
j += (n << 23);
if ((j >> 23) <= 0)
z = basicmath___scalbnf(z, n); /* subnormal output */
else
SET_FLOAT_WORD(z, j);
return s * z;
}
/* e_rem_pio2f.c -- float version of e_rem_pio2.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/* basicmath___ieee754_rem_pio2f(x,y)
return the remainder of x rem pi/2 in y[0]+y[1]
*/
/* This array is like the one in e_rem_pio2.c, but the numbers are
single precision and the last 8 bits are forced to 0. */
static const int32_t basicmath_npio2_hw[] = {
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
0x4242c700, 0x42490f00};
/*
invpio2: 24 bits of 2/pi
pio2_1: first 17 bit of pi/2
pio2_1t: pi/2 - pio2_1
pio2_2: second 17 bit of pi/2
pio2_2t: pi/2 - (pio2_1+pio2_2)
pio2_3: third 17 bit of pi/2
pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const float basicmath_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
basicmath_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
basicmath_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
basicmath_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
basicmath_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
basicmath_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
basicmath_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
__attribute__((always_inline)) static inline int32_t
basicmath___ieee754_rem_pio2f(float x, float *y) {
float z, w, t, r, fn;
int32_t i, j, n, ix, hx;
GET_FLOAT_WORD(hx, x);
ix = hx & 0x7fffffff;
if (ix <= 0x3f490fd8) { /* |x| ~<= pi/4 , no need for reduction */
y[0] = x;
y[1] = 0;
return 0;
}
if (ix < 0x4016cbe4) { /* |x| < 3pi/4, special case with n=+-1 */
if (hx > 0) {
z = x - basicmath_pio2_1;
if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */
y[0] = z - basicmath_pio2_1t;
y[1] = (z - y[0]) - basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z -= basicmath_pio2_2;
y[0] = z - basicmath_pio2_2t;
y[1] = (z - y[0]) - basicmath_pio2_2t;
}
return 1;
} else { /* negative x */
z = x + basicmath_pio2_1;
if ((ix & 0xfffffff0) != 0x3fc90fd0) { /* 24+24 bit pi OK */
y[0] = z + basicmath_pio2_1t;
y[1] = (z - y[0]) + basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z += basicmath_pio2_2;
y[0] = z + basicmath_pio2_2t;
y[1] = (z - y[0]) + basicmath_pio2_2t;
}
return -1;
}
}
if (ix <= 0x43490f80) { /* |x| ~<= 2^7*(pi/2), medium size */
t = basicmath___fabsf(x);
n = (int32_t) (t * basicmath_invpio2 + basicmath_half);
fn = (float) n;
r = t - fn * basicmath_pio2_1;
w = fn * basicmath_pio2_1t; /* 1st round good to 40 bit */
if (n < 32 &&
(int32_t) (ix & 0xffffff00) != basicmath_npio2_hw[n - 1]) {
y[0] = r - w; /* quick check no cancellation */
} else {
u_int32_t high;
j = ix >> 23;
y[0] = r - w;
GET_FLOAT_WORD(high, y[0]);
i = j - ((high >> 23) & 0xff);
if (i > 8) { /* 2nd iteration needed, good to 57 */
t = r;
w = fn * basicmath_pio2_2;
r = t - w;
w = fn * basicmath_pio2_2t - ((t - r) - w);
y[0] = r - w;
GET_FLOAT_WORD(high, y[0]);
i = j - ((high >> 23) & 0xff);
if (i > 25) { /* 3rd iteration need, 74 bits acc */
t = r; /* will cover all possible cases */
w = fn * basicmath_pio2_3;
r = t - w;
w = fn * basicmath_pio2_3t - ((t - r) - w);
y[0] = r - w;
}
}
}
y[1] = (r - y[0]) - w;
if (hx < 0) {
y[0] = -y[0];
y[1] = -y[1];
return -n;
} else
return n;
}
/*
all other (large) arguments
*/
if (ix >= 0x7f800000) { /* x is inf or NaN */
y[0] = y[1] = x - x;
return 0;
}
// This will never happen in basicmath_small, because
// up to this point we have already returned a value
// for each of the possible inputs
y[0] = y[1] = x - x; /* dummy initialization */
return 0;
}
/* e_sqrtf.c -- float version of e_sqrt.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
__attribute__((always_inline)) static inline float
basicmath___ieee754_sqrtf(float x) {
float z;
int32_t sign = (int) 0x80000000;
int32_t ix, s, q, m, t, i;
u_int32_t r;
GET_FLOAT_WORD(ix, x);
/* take care of Inf and NaN */
if ((ix & 0x7f800000) == 0x7f800000) {
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if (ix <= 0) {
if ((ix & (~sign)) == 0)
return x; /* sqrt(+-0) = +-0 */
else if (ix < 0)
return (x - x) / (x - x); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = (ix >> 23);
if (m == 0) { /* subnormal x */
__pragma_loopbound(0, 0);
for (i = 0; (ix & 0x00800000) == 0; i++)
ix <<= 1;
m -= i - 1;
}
m -= 127; /* unbias exponent */
ix = (ix & 0x007fffff) | 0x00800000;
if (m & 1) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
__pragma_loopbound(25, 25);
while (r != 0) {
t = s + r;
if (t <= ix) {
s = t + r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
/* use floating add to find out rounding direction */
if (ix != 0) {
z = basicmath_one - basicmath_tiny; /* trigger inexact flag */
if (z >= basicmath_one) {
z = basicmath_one + basicmath_tiny;
if (z > basicmath_one)
q += 2;
else
q += (q & 1);
}
}
ix = (q >> 1) + 0x3f000000;
ix += (m << 23);
SET_FLOAT_WORD(z, ix);
return z;
}
/* k_cosf.c -- float version of k_cos.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
basicmath_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
basicmath_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
basicmath_C4 = -2.7557314297e-07f, /* 0xb493f27c */
basicmath_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
basicmath_C6 = -1.1359647598e-11f; /* 0xad47d74e */
__attribute__((always_inline)) static inline float
basicmath___kernel_cosf(float x, float y) {
float a, hz, z, r, qx;
int32_t ix;
GET_FLOAT_WORD(ix, x);
ix &= 0x7fffffff; /* ix = |x|'s high word*/
if (ix < 0x32000000) { /* if x < 2**27 */
if (((int) x) == 0)
return basicmath_one; /* generate inexact */
}
z = x * x;
r = z * (basicmath_C1 +
z * (basicmath_C2 +
z * (basicmath_C3 +
z * (basicmath_C4 +
z * (basicmath_C5 + z * basicmath_C6)))));
if (ix < 0x3e99999a) /* if |x| < 0.3 */
return basicmath_one - ((float) 0.5f * z - (z * r - x * y));
else {
if (ix > 0x3f480000) /* x > 0.78125 */
qx = (float) 0.28125f;
else {
SET_FLOAT_WORD(qx, ix - 0x01000000); /* x/4 */
}
hz = (float) 0.5f * z - qx;
a = basicmath_one - qx;
return a - (hz - (z * r - x * y));
}
}
/* k_sinf.c -- float version of k_sin.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
basicmath_S2 = 8.3333337680e-03f, /* 0x3c088889 */
basicmath_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
basicmath_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
basicmath_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
basicmath_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
__attribute__((always_inline)) static inline float
basicmath___kernel_sinf(float x, float y, int iy) {
float z, r, v;
int32_t ix;
GET_FLOAT_WORD(ix, x);
ix &= 0x7fffffff; /* high word of x */
if (ix < 0x32000000) { /* |x| < 2**-27 */
if ((int) x == 0)
return x; /* generate inexact */
}
z = x * x;
v = z * x;
r = basicmath_S2 +
z * (basicmath_S3 +
z * (basicmath_S4 + z * (basicmath_S5 + z * basicmath_S6)));
if (iy == 0)
return x + v * (basicmath_S1 + z * r);
else
return x - ((z * (basicmath_half * y - v * r) - y) - v * basicmath_S1);
}
/* s_copysignf.c -- float version of s_copysign.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
copysignf(float x, float y)
copysignf(x,y) returns a value with the magnitude of x and
with the sign bit of y.
*/
__attribute__((always_inline)) static inline float
basicmath___copysignf(float x, float y) {
u_int32_t ix, iy;
GET_FLOAT_WORD(ix, x);
GET_FLOAT_WORD(iy, y);
SET_FLOAT_WORD(x, (ix & 0x7fffffff) | (iy & 0x80000000));
return x;
}
/* s_cosf.c -- float version of s_cos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
__attribute__((always_inline)) static inline float
basicmath___cosf(float x) {
float y[2], z = 0.0f;
int32_t n, ix;
GET_FLOAT_WORD(ix, x);
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if (ix <= 0x3f490fd8)
return basicmath___kernel_cosf(x, z);
/* cos(Inf or NaN) is NaN */
else if (ix >= 0x7f800000)
return x - x;
/* argument reduction needed */
else {
n = basicmath___ieee754_rem_pio2f(x, y);
switch (n & 3) {
case 0:
return basicmath___kernel_cosf(y[0], y[1]);
case 1:
return -basicmath___kernel_sinf(y[0], y[1], 1);
case 2:
return -basicmath___kernel_cosf(y[0], y[1]);
default:
return basicmath___kernel_sinf(y[0], y[1], 1);
}
}
}
/* s_fabsf.c -- float version of s_fabs.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
fabsf(x) returns the absolute value of x.
*/
__attribute__((always_inline)) static inline float
basicmath___fabsf(float x) {
u_int32_t ix;
GET_FLOAT_WORD(ix, x);
SET_FLOAT_WORD(x, ix & 0x7fffffff);
return x;
}
/*
isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
no branching!
*/
__attribute__((always_inline)) static inline int
basicmath___isinff(float x) {
int32_t ix, t;
GET_FLOAT_WORD(ix, x);
t = ix & 0x7fffffff;
t ^= 0x7f800000;
t |= -t;
return ~(t >> 31) & (ix >> 30);
}
/* s_scalbnf.c -- float version of s_scalbn.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_two25 = 3.355443200e+07f, /* 0x4c000000 */
basicmath_twom25 = 2.9802322388e-08f; /* 0x33000000 */
__attribute__((always_inline)) static inline float
basicmath___scalbnf(float x, int n) {
int32_t k, ix;
GET_FLOAT_WORD(ix, x);
k = (ix & 0x7f800000) >> 23; /* extract exponent */
if (k == 0) { /* 0 or subnormal x */
if ((ix & 0x7fffffff) == 0)
return x; /* +-0 */
x *= basicmath_two25;
GET_FLOAT_WORD(ix, x);
k = ((ix & 0x7f800000) >> 23) - 25;
}
if (k == 0xff)
return x + x; /* NaN or Inf */
k = k + n;
if (n > 50000 || k > 0xfe)
return basicmath_huge *
basicmath___copysignf(basicmath_huge, x); /* overflow */
if (n < -50000)
return basicmath_tiny *
basicmath___copysignf(basicmath_tiny, x); /*underflow*/
if (k > 0) { /* normal result */
SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
return x;
}
if (k <= -25)
return basicmath_tiny *
basicmath___copysignf(basicmath_tiny, x); /*underflow*/
k += 25; /* subnormal result */
SET_FLOAT_WORD(x, (ix & 0x807fffff) | (k << 23));
return x * basicmath_twom25;
}

View File

@ -0,0 +1,66 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _WCCLIBM
#define _WCCLIBM
#define int32_t int
#define u_int32_t unsigned int
// Often used variables/consts
static const float basicmath_one = 1.0f, basicmath_tiny = 1.0e-30f,
basicmath_half = 5.0000000000e-01, /* 0x3f000000 */
basicmath_huge = 1.0e30, basicmath_two = 2.0,
basicmath_two24 = 16777216.0, /* 0x4b800000 */
basicmath_zero = 0.0;
__attribute__((always_inline)) static inline float
basicmath___copysignf(float x, float y);
__attribute__((always_inline)) static inline float basicmath___cosf(float x);
__attribute__((always_inline)) static inline float basicmath___fabsf(float x);
__attribute__((always_inline)) static inline float
basicmath___ieee754_acosf(float x);
__attribute__((always_inline)) static inline float
basicmath___ieee754_powf(float x, float y);
__attribute__((always_inline)) static inline int32_t
basicmath___ieee754_rem_pio2f(float x, float *y);
__attribute__((always_inline)) static inline float
basicmath___ieee754_sqrtf(float x);
__attribute__((always_inline)) static inline int basicmath___isinff(float x);
__attribute__((always_inline)) static inline float
basicmath___kernel_cosf(float x, float y);
__attribute__((always_inline)) static inline float
basicmath___kernel_sinf(float x, float y, int iy);
__attribute__((always_inline)) static inline float basicmath___scalbnf(float x,
int n);
#endif // _WCCLIBM

View File

@ -0,0 +1,68 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
from: @(#)fdlibm.h 5.1 93/09/24
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: math_private.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: fdlibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _MATH_PRIVATE_H_
#define _MATH_PRIVATE_H_
#include "wcclibm.h"
/* A union which permits us to convert between a float and a 32 bit int. */
typedef union {
float value;
u_int32_t word;
} ieee_float_shape_type;
/* Get a 32 bit int from a float. */
#define GET_FLOAT_WORD(i,d) \
{ \
ieee_float_shape_type gf_u; \
gf_u.value = (d); \
(i) = gf_u.word; \
}
/* Set a float from a 32 bit int. */
#define SET_FLOAT_WORD(d,i) \
{ \
ieee_float_shape_type sf_u; \
sf_u.word = (i); \
(d) = sf_u.value; \
}
#endif /* _MATH_PRIVATE_H_ */

View File

@ -0,0 +1,31 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: pi
Author: unknown
Function: Header file for definition of pi
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
#ifndef PI__H
#define PI__H
#ifndef PI
#define PI 3.14f
#endif
#endif /* PI__H */

View File

@ -0,0 +1,40 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: snipmath
Author: unknown
Function: Header file for SNIPPETS math functions and macros
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
/*
SNIPMATH.H - Header file for SNIPPETS math functions and macros
*/
#ifndef SNIPMATH__H
#define SNIPMATH__H
#include "wcclibm.h"
#include "pi.h"
struct int_sqrt {
unsigned short sqrt,
frac;
};
#endif /* SNIPMATH__H */

View File

@ -0,0 +1,757 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.c
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.c
Changes: No major functional changes.
License: See the terms above.
*/
#include "wcclibm.h"
#include "math_private.h"
/* e_acosf.c -- float version of e_acos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_pi = 3.1415925026e+00f, /* 0x40490fda */
basicmath_pio2_hi = 1.5707962513e+00f, /* 0x3fc90fda */
basicmath_pio2_lo = 7.5497894159e-08f, /* 0x33a22168 */
basicmath_pS0 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_pS1 = -3.2556581497e-01f, /* 0xbea6b090 */
basicmath_pS2 = 2.0121252537e-01f, /* 0x3e4e0aa8 */
basicmath_pS3 = -4.0055535734e-02f, /* 0xbd241146 */
basicmath_pS4 = 7.9153501429e-04f, /* 0x3a4f7f04 */
basicmath_pS5 = 3.4793309169e-05f, /* 0x3811ef08 */
basicmath_qS1 = -2.4033949375e+00f, /* 0xc019d139 */
basicmath_qS2 = 2.0209457874e+00f, /* 0x4001572d */
basicmath_qS3 = -6.8828397989e-01f, /* 0xbf303361 */
basicmath_qS4 = 7.7038154006e-02f; /* 0x3d9dc62e */
float basicmath___ieee754_acosf( float x )
{
float z, p, q, r, w, s, c, df;
int32_t hx, ix;
GET_FLOAT_WORD( hx, x );
ix = hx & 0x7fffffff;
if ( ix == 0x3f800000 ) { /* |x|==1 */
if ( hx > 0 ) return 0.0f; /* acos(1) = 0 */
else return basicmath_pi + ( float )2.0f * basicmath_pio2_lo; /* acos(-1)= pi */
} else
if ( ix > 0x3f800000 ) { /* |x| >= 1 */
return ( x - x ) / ( x - x ); /* acos(|x|>1) is NaN */
}
if ( ix < 0x3f000000 ) { /* |x| < 0.5 */
if ( ix <= 0x23000000 ) return basicmath_pio2_hi +
basicmath_pio2_lo; /*if|x|<2**-57*/
z = x * x;
p = z * ( basicmath_pS0 + z * ( basicmath_pS1 + z * ( basicmath_pS2 + z *
( basicmath_pS3 + z *
( basicmath_pS4 + z * basicmath_pS5 ) ) ) ) );
q = basicmath_one + z * ( basicmath_qS1 + z * ( basicmath_qS2 + z *
( basicmath_qS3 + z * basicmath_qS4 ) ) );
r = p / q;
return basicmath_pio2_hi - ( x - ( basicmath_pio2_lo - x * r ) );
} else
if ( hx < 0 ) { /* x < -0.5 */
z = ( basicmath_one + x ) * ( float )0.5f;
p = z * ( basicmath_pS0 + z * ( basicmath_pS1 + z * ( basicmath_pS2 + z *
( basicmath_pS3 + z *
( basicmath_pS4 + z * basicmath_pS5 ) ) ) ) );
q = basicmath_one + z * ( basicmath_qS1 + z * ( basicmath_qS2 + z *
( basicmath_qS3 + z * basicmath_qS4 ) ) );
s = basicmath___ieee754_sqrtf( z );
r = p / q;
w = r * s - basicmath_pio2_lo;
return basicmath_pi - ( float )2.0f * ( s + w );
} else { /* x > 0.5 */
int32_t idf;
z = ( basicmath_one - x ) * ( float )0.5f;
s = basicmath___ieee754_sqrtf( z );
df = s;
GET_FLOAT_WORD( idf, df );
SET_FLOAT_WORD( df, idf & 0xfffff000 );
c = ( z - df * df ) / ( s + df );
p = z * ( basicmath_pS0 + z * ( basicmath_pS1 + z * ( basicmath_pS2 + z *
( basicmath_pS3 + z *
( basicmath_pS4 + z * basicmath_pS5 ) ) ) ) );
q = basicmath_one + z * ( basicmath_qS1 + z * ( basicmath_qS2 + z *
( basicmath_qS3 + z * basicmath_qS4 ) ) );
r = p / q;
w = r * s + c;
return ( float )2.0f * ( df + w );
}
}
/* e_powf.c -- float version of e_pow.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_bp[] = {1.0f, 1.5f,},
basicmath_dp_h[] = { 0.0f, 5.84960938e-01f,}, /* 0x3f15c000 */
basicmath_dp_l[] = { 0.0f, 1.56322085e-06f,}, /* 0x35d1cfdc */
/* poly coefs for (3/2)*(log(x)-2s-2/3*s**3 */
basicmath_L1 = 6.0000002384e-01f, /* 0x3f19999a */
basicmath_L2 = 4.2857143283e-01f, /* 0x3edb6db7 */
basicmath_L3 = 3.3333334327e-01f, /* 0x3eaaaaab */
basicmath_L4 = 2.7272811532e-01f, /* 0x3e8ba305 */
basicmath_L5 = 2.3066075146e-01f, /* 0x3e6c3255 */
basicmath_L6 = 2.0697501302e-01f, /* 0x3e53f142 */
basicmath_P1 = 1.6666667163e-01f, /* 0x3e2aaaab */
basicmath_P2 = -2.7777778450e-03f, /* 0xbb360b61 */
basicmath_P3 = 6.6137559770e-05f, /* 0x388ab355 */
basicmath_P4 = -1.6533901999e-06f, /* 0xb5ddea0e */
basicmath_P5 = 4.1381369442e-08f, /* 0x3331bb4c */
basicmath_lg2 = 6.9314718246e-01f, /* 0x3f317218 */
basicmath_lg2_h = 6.93145752e-01f, /* 0x3f317200 */
basicmath_lg2_l = 1.42860654e-06f, /* 0x35bfbe8c */
basicmath_ovt = 4.2995665694e-08f, /* -(128-log2(ovfl+.5ulp)) */
basicmath_cp = 9.6179670095e-01f, /* 0x3f76384f =2/(3ln2) */
basicmath_cp_h = 9.6179199219e-01f, /* 0x3f763800 =head of cp */
basicmath_cp_l = 4.7017383622e-06f, /* 0x369dc3a0 =tail of cp_h */
basicmath_ivln2 = 1.4426950216e+00f, /* 0x3fb8aa3b =1/ln2 */
basicmath_ivln2_h = 1.4426879883e+00f, /* 0x3fb8aa00 =16b 1/ln2*/
basicmath_ivln2_l = 7.0526075433e-06f; /* 0x36eca570 =1/ln2 tail*/
float basicmath___ieee754_powf( float x, float y )
{
float z, ax, z_h, z_l, p_h, p_l;
float y1, t1, t2, r, s, t, u, v, w;
int32_t i, j, k, yisint, n;
int32_t hx, hy, ix, iy, is;
GET_FLOAT_WORD( hx, x );
GET_FLOAT_WORD( hy, y );
ix = hx & 0x7fffffff;
iy = hy & 0x7fffffff;
/* y==zero: x**0 = 1 */
if ( iy == 0 ) return basicmath_one;
/* x==+-1 */
if ( x == 1.0f ) return basicmath_one;
if ( x == -1.0f && basicmath___isinff( y ) ) return basicmath_one;
/* +-NaN return x+y */
if ( ix > 0x7f800000 ||
iy > 0x7f800000 )
return x + y;
/* determine if y is an odd int when x < 0
yisint = 0 ... y is not an integer
yisint = 1 ... y is an odd int
yisint = 2 ... y is an even int
*/
yisint = 0;
if ( hx < 0 ) {
if ( iy >= 0x4b800000 ) yisint = 2; /* even integer y */
else
if ( iy >= 0x3f800000 ) {
k = ( iy >> 23 ) - 0x7f; /* exponent */
j = iy >> ( 23 - k );
if ( ( j << ( 23 - k ) ) == iy ) yisint = 2 - ( j & 1 );
}
}
/* special value of y */
if ( iy == 0x7f800000 ) { /* y is +-inf */
if ( ix == 0x3f800000 )
return y - y; /* inf**+-1 is NaN */
else
if ( ix > 0x3f800000 ) /* (|x|>1)**+-inf = inf,0 */
return ( hy >= 0 ) ? y : basicmath_zero;
else /* (|x|<1)**-,+inf = inf,0 */
return ( hy < 0 ) ? -y : basicmath_zero;
}
if ( iy == 0x3f800000 ) { /* y is +-1 */
if ( hy < 0 ) return basicmath_one / x;
else return x;
}
if ( hy == 0x40000000 ) return x * x; /* y is 2 */
if ( hy == 0x3f000000 ) { /* y is 0.5 */
if ( hx >= 0 ) /* x >= +0 */
return basicmath___ieee754_sqrtf( x );
}
ax = basicmath___fabsf( x );
/* special value of x */
if ( ix == 0x7f800000 || ix == 0 || ix == 0x3f800000 ) {
z = ax; /*x is +-0,+-inf,+-1*/
if ( hy < 0 ) z = basicmath_one / z; /* z = (1/|x|) */
if ( hx < 0 ) {
if ( ( ( ix - 0x3f800000 ) | yisint ) == 0 ) {
z = ( z - z ) / ( z - z ); /* (-1)**non-int is NaN */
} else
if ( yisint == 1 )
z = -z; /* (x<0)**odd = -(|x|**odd) */
}
return z;
}
/* (x<0)**(non-int) is NaN */
if ( ( ( ( ( u_int32_t )hx >> 31 ) - 1 ) | yisint ) == 0 ) return ( x - x ) /
( x - x );
/* |y| is huge */
if ( iy > 0x4d000000 ) { /* if |y| > 2**27 */
/* over/underflow if x is not close to one */
if ( ix < 0x3f7ffff8 ) return ( hy < 0 ) ? basicmath_huge * basicmath_huge :
basicmath_tiny * basicmath_tiny;
if ( ix > 0x3f800007 ) return ( hy > 0 ) ? basicmath_huge * basicmath_huge :
basicmath_tiny * basicmath_tiny;
/* now |1-x| is tiny <= 2**-20, suffice to compute
log(x) by x-x^2/2+x^3/3-x^4/4 */
t = x - 1; /* t has 20 trailing zeros */
w = ( t * t ) * ( ( float )0.5f - t * ( ( float )0.333333333333f - t *
( float )0.25f ) );
u = basicmath_ivln2_h * t; /* ivln2_h has 16 sig. bits */
v = t * basicmath_ivln2_l - w * basicmath_ivln2;
t1 = u + v;
GET_FLOAT_WORD( is, t1 );
SET_FLOAT_WORD( t1, is & 0xfffff000 );
t2 = v - ( t1 - u );
} else {
float s2, s_h, s_l, t_h, t_l;
n = 0;
/* take care subnormal number */
if ( ix < 0x00800000 ) {
ax *= basicmath_two24;
n -= 24;
GET_FLOAT_WORD( ix, ax );
}
n += ( ( ix ) >> 23 ) - 0x7f;
j = ix & 0x007fffff;
/* determine interval */
ix = j | 0x3f800000; /* normalize ix */
if ( j <= 0x1cc471 ) k = 0; /* |x|<sqrt(3/2) */
else
if ( j < 0x5db3d7 ) k = 1; /* |x|<sqrt(3) */
else {
k = 0;
n += 1;
ix -= 0x00800000;
}
SET_FLOAT_WORD( ax, ix );
/* compute s = s_h+s_l = (x-1)/(x+1) or (x-1.5)/(x+1.5) */
u = ax - basicmath_bp[ k ]; /* bp[0]=1.0, bp[1]=1.5 */
v = basicmath_one / ( ax + basicmath_bp[ k ] );
s = u * v;
s_h = s;
GET_FLOAT_WORD( is, s_h );
SET_FLOAT_WORD( s_h, is & 0xfffff000 );
/* t_h=ax+bp[k] High */
SET_FLOAT_WORD( t_h, ( ( ix >> 1 ) | 0x20000000 ) + 0x0040000 + ( k << 21 ) );
t_l = ax - ( t_h - basicmath_bp[ k ] );
s_l = v * ( ( u - s_h * t_h ) - s_h * t_l );
/* compute log(ax) */
s2 = s * s;
r = s2 * s2 * ( basicmath_L1 + s2 * ( basicmath_L2 + s2 *
( basicmath_L3 + s2 * ( basicmath_L4 + s2 *
( basicmath_L5 + s2 * basicmath_L6 ) ) ) ) );
r += s_l * ( s_h + s );
s2 = s_h * s_h;
t_h = ( float )3.0f + s2 + r;
GET_FLOAT_WORD( is, t_h );
SET_FLOAT_WORD( t_h, is & 0xfffff000 );
t_l = r - ( ( t_h - ( float )3.0f ) - s2 );
/* u+v = s*(1+...) */
u = s_h * t_h;
v = s_l * t_h + t_l * s;
/* 2/(3log2)*(s+...) */
p_h = u + v;
GET_FLOAT_WORD( is, p_h );
SET_FLOAT_WORD( p_h, is & 0xfffff000 );
p_l = v - ( p_h - u );
z_h = basicmath_cp_h * p_h; /* cp_h+cp_l = 2/(3*log2) */
z_l = basicmath_cp_l * p_h + p_l * basicmath_cp + basicmath_dp_l[ k ];
/* log2(ax) = (s+..)*2/(3*log2) = n + dp_h + z_h + z_l */
t = ( float )n;
t1 = ( ( ( z_h + z_l ) + basicmath_dp_h[ k ] ) + t );
GET_FLOAT_WORD( is, t1 );
SET_FLOAT_WORD( t1, is & 0xfffff000 );
t2 = z_l - ( ( ( t1 - t ) - basicmath_dp_h[ k ] ) - z_h );
}
s = basicmath_one; /* s (sign of result -ve**odd) = -1 else = 1 */
if ( ( ( ( ( u_int32_t )hx >> 31 ) - 1 ) | ( yisint - 1 ) ) == 0 )
s = -basicmath_one; /* (-ve)**(odd int) */
/* split up y into y1+y2 and compute (y1+y2)*(t1+t2) */
GET_FLOAT_WORD( is, y );
SET_FLOAT_WORD( y1, is & 0xfffff000 );
p_l = ( y - y1 ) * t1 + y * t2;
p_h = y1 * t1;
z = p_l + p_h;
GET_FLOAT_WORD( j, z );
if ( j > 0x43000000 ) /* if z > 128 */
return s * basicmath_huge * basicmath_huge; /* overflow */
else
if ( j == 0x43000000 ) { /* if z == 128 */
if ( p_l + basicmath_ovt > z - p_h ) return s * basicmath_huge *
basicmath_huge; /* overflow */
} else
if ( ( j & 0x7fffffff ) > 0x43160000 ) /* z <= -150 */
return s * basicmath_tiny * basicmath_tiny; /* underflow */
else
if ( ( u_int32_t ) j == 0xc3160000 ) { /* z == -150 */
if ( p_l <= z - p_h ) return s * basicmath_tiny *
basicmath_tiny; /* underflow */
}
/*
compute 2**(p_h+p_l)
*/
i = j & 0x7fffffff;
k = ( i >> 23 ) - 0x7f;
n = 0;
if ( i > 0x3f000000 ) { /* if |z| > 0.5, set n = [z+0.5] */
n = j + ( 0x00800000 >> ( k + 1 ) );
k = ( ( n & 0x7fffffff ) >> 23 ) - 0x7f; /* new k for n */
SET_FLOAT_WORD( t, n & ~( 0x007fffff >> k ) );
n = ( ( n & 0x007fffff ) | 0x00800000 ) >> ( 23 - k );
if ( j < 0 ) n = -n;
p_h -= t;
}
t = p_l + p_h;
GET_FLOAT_WORD( is, t );
SET_FLOAT_WORD( t, is & 0xfffff000 );
u = t * basicmath_lg2_h;
v = ( p_l - ( t - p_h ) ) * basicmath_lg2 + t * basicmath_lg2_l;
z = u + v;
w = v - ( z - u );
t = z * z;
t1 = z - t * ( basicmath_P1 + t * ( basicmath_P2 + t * ( basicmath_P3 + t *
( basicmath_P4 + t * basicmath_P5 ) ) ) );
r = ( z * t1 ) / ( t1 - basicmath_two ) - ( w + z * w );
z = basicmath_one - ( r - z );
GET_FLOAT_WORD( j, z );
j += ( n << 23 );
if ( ( j >> 23 ) <= 0 ) z = basicmath___scalbnf( z, n ); /* subnormal output */
else SET_FLOAT_WORD( z, j );
return s * z;
}
/* e_rem_pio2f.c -- float version of e_rem_pio2.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/* basicmath___ieee754_rem_pio2f(x,y)
return the remainder of x rem pi/2 in y[0]+y[1]
*/
/* This array is like the one in e_rem_pio2.c, but the numbers are
single precision and the last 8 bits are forced to 0. */
static const int32_t basicmath_npio2_hw[] = {
0x3fc90f00, 0x40490f00, 0x4096cb00, 0x40c90f00, 0x40fb5300, 0x4116cb00,
0x412fed00, 0x41490f00, 0x41623100, 0x417b5300, 0x418a3a00, 0x4196cb00,
0x41a35c00, 0x41afed00, 0x41bc7e00, 0x41c90f00, 0x41d5a000, 0x41e23100,
0x41eec200, 0x41fb5300, 0x4203f200, 0x420a3a00, 0x42108300, 0x4216cb00,
0x421d1400, 0x42235c00, 0x4229a500, 0x422fed00, 0x42363600, 0x423c7e00,
0x4242c700, 0x42490f00
};
/*
invpio2: 24 bits of 2/pi
pio2_1: first 17 bit of pi/2
pio2_1t: pi/2 - pio2_1
pio2_2: second 17 bit of pi/2
pio2_2t: pi/2 - (pio2_1+pio2_2)
pio2_3: third 17 bit of pi/2
pio2_3t: pi/2 - (pio2_1+pio2_2+pio2_3)
*/
static const float basicmath_invpio2 = 6.3661980629e-01f, /* 0x3f22f984 */
basicmath_pio2_1 = 1.5707855225e+00f, /* 0x3fc90f80 */
basicmath_pio2_1t = 1.0804334124e-05f, /* 0x37354443 */
basicmath_pio2_2 = 1.0804273188e-05f, /* 0x37354400 */
basicmath_pio2_2t = 6.0770999344e-11f, /* 0x2e85a308 */
basicmath_pio2_3 = 6.0770943833e-11f, /* 0x2e85a300 */
basicmath_pio2_3t = 6.1232342629e-17f; /* 0x248d3132 */
int32_t basicmath___ieee754_rem_pio2f( float x, float *y )
{
float z, w, t, r, fn;
int32_t i, j, n, ix, hx;
GET_FLOAT_WORD( hx, x );
ix = hx & 0x7fffffff;
if ( ix <= 0x3f490fd8 ) { /* |x| ~<= pi/4 , no need for reduction */
y[ 0 ] = x;
y[ 1 ] = 0;
return 0;
}
if ( ix < 0x4016cbe4 ) { /* |x| < 3pi/4, special case with n=+-1 */
if ( hx > 0 ) {
z = x - basicmath_pio2_1;
if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) { /* 24+24 bit pi OK */
y[ 0 ] = z - basicmath_pio2_1t;
y[ 1 ] = ( z - y[ 0 ] ) - basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z -= basicmath_pio2_2;
y[ 0 ] = z - basicmath_pio2_2t;
y[ 1 ] = ( z - y[ 0 ] ) - basicmath_pio2_2t;
}
return 1;
} else { /* negative x */
z = x + basicmath_pio2_1;
if ( ( ix & 0xfffffff0 ) != 0x3fc90fd0 ) { /* 24+24 bit pi OK */
y[ 0 ] = z + basicmath_pio2_1t;
y[ 1 ] = ( z - y[ 0 ] ) + basicmath_pio2_1t;
} else { /* near pi/2, use 24+24+24 bit pi */
z += basicmath_pio2_2;
y[ 0 ] = z + basicmath_pio2_2t;
y[ 1 ] = ( z - y[ 0 ] ) + basicmath_pio2_2t;
}
return -1;
}
}
if ( ix <= 0x43490f80 ) { /* |x| ~<= 2^7*(pi/2), medium size */
t = basicmath___fabsf( x );
n = ( int32_t ) ( t * basicmath_invpio2 + basicmath_half );
fn = ( float )n;
r = t - fn * basicmath_pio2_1;
w = fn * basicmath_pio2_1t; /* 1st round good to 40 bit */
if ( n < 32 && ( int32_t )( ix & 0xffffff00 ) != basicmath_npio2_hw[n - 1] ) {
y[ 0 ] = r - w; /* quick check no cancellation */
} else {
u_int32_t high;
j = ix >> 23;
y[ 0 ] = r - w;
GET_FLOAT_WORD( high, y[ 0 ] );
i = j - ( ( high >> 23 ) & 0xff );
if ( i > 8 ) { /* 2nd iteration needed, good to 57 */
t = r;
w = fn * basicmath_pio2_2;
r = t - w;
w = fn * basicmath_pio2_2t - ( ( t - r ) - w );
y[ 0 ] = r - w;
GET_FLOAT_WORD( high, y[ 0 ] );
i = j - ( ( high >> 23 ) & 0xff );
if ( i > 25 ) { /* 3rd iteration need, 74 bits acc */
t = r; /* will cover all possible cases */
w = fn * basicmath_pio2_3;
r = t - w;
w = fn * basicmath_pio2_3t - ( ( t - r ) - w );
y[ 0 ] = r - w;
}
}
}
y[ 1 ] = ( r - y[ 0 ] ) - w;
if ( hx < 0 ) {
y[ 0 ] = -y[ 0 ];
y[ 1 ] = -y[ 1 ];
return -n;
} else return n;
}
/*
all other (large) arguments
*/
if ( ix >= 0x7f800000 ) { /* x is inf or NaN */
y[ 0 ] = y[ 1 ] = x - x;
return 0;
}
// This will never happen in basicmath_small, because
// up to this point we have already returned a value
// for each of the possible inputs
y[ 0 ] = y[ 1 ] = x - x; /* dummy initialization */
return 0;
}
/* e_sqrtf.c -- float version of e_sqrt.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
float basicmath___ieee754_sqrtf( float x )
{
float z;
int32_t sign = ( int )0x80000000;
int32_t ix, s, q, m, t, i;
u_int32_t r;
GET_FLOAT_WORD( ix, x );
/* take care of Inf and NaN */
if ( ( ix & 0x7f800000 ) == 0x7f800000 ) {
return x * x + x; /* sqrt(NaN)=NaN, sqrt(+inf)=+inf
sqrt(-inf)=sNaN */
}
/* take care of zero */
if ( ix <= 0 ) {
if ( ( ix & ( ~sign ) ) == 0 ) return x; /* sqrt(+-0) = +-0 */
else
if ( ix < 0 )
return ( x - x ) / ( x - x ); /* sqrt(-ve) = sNaN */
}
/* normalize x */
m = ( ix >> 23 );
if ( m == 0 ) { /* subnormal x */
_Pragma( "loopbound min 0 max 0" )
for ( i = 0; ( ix & 0x00800000 ) == 0; i++ )
ix <<= 1;
m -= i - 1;
}
m -= 127; /* unbias exponent */
ix = ( ix & 0x007fffff ) | 0x00800000;
if ( m & 1 ) /* odd m, double x to make it even */
ix += ix;
m >>= 1; /* m = [m/2] */
/* generate sqrt(x) bit by bit */
ix += ix;
q = s = 0; /* q = sqrt(x) */
r = 0x01000000; /* r = moving bit from right to left */
_Pragma( "loopbound min 25 max 25" )
while ( r != 0 ) {
t = s + r;
if ( t <= ix ) {
s = t + r;
ix -= t;
q += r;
}
ix += ix;
r >>= 1;
}
/* use floating add to find out rounding direction */
if ( ix != 0 ) {
z = basicmath_one - basicmath_tiny; /* trigger inexact flag */
if ( z >= basicmath_one ) {
z = basicmath_one + basicmath_tiny;
if ( z > basicmath_one )
q += 2;
else
q += ( q & 1 );
}
}
ix = ( q >> 1 ) + 0x3f000000;
ix += ( m << 23 );
SET_FLOAT_WORD( z, ix );
return z;
}
/* k_cosf.c -- float version of k_cos.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_C1 = 4.1666667908e-02f, /* 0x3d2aaaab */
basicmath_C2 = -1.3888889225e-03f, /* 0xbab60b61 */
basicmath_C3 = 2.4801587642e-05f, /* 0x37d00d01 */
basicmath_C4 = -2.7557314297e-07f, /* 0xb493f27c */
basicmath_C5 = 2.0875723372e-09f, /* 0x310f74f6 */
basicmath_C6 = -1.1359647598e-11f; /* 0xad47d74e */
float basicmath___kernel_cosf( float x, float y )
{
float a, hz, z, r, qx;
int32_t ix;
GET_FLOAT_WORD( ix, x );
ix &= 0x7fffffff; /* ix = |x|'s high word*/
if ( ix < 0x32000000 ) { /* if x < 2**27 */
if ( ( ( int )x ) == 0 ) return basicmath_one; /* generate inexact */
}
z = x * x;
r = z * ( basicmath_C1 + z * ( basicmath_C2 + z * ( basicmath_C3 + z *
( basicmath_C4 + z * ( basicmath_C5 + z * basicmath_C6 ) ) ) ) );
if ( ix < 0x3e99999a ) /* if |x| < 0.3 */
return basicmath_one - ( ( float )0.5f * z - ( z * r - x * y ) );
else {
if ( ix > 0x3f480000 ) /* x > 0.78125 */
qx = ( float )0.28125f;
else {
SET_FLOAT_WORD( qx, ix - 0x01000000 ); /* x/4 */
}
hz = ( float )0.5f * z - qx;
a = basicmath_one - qx;
return a - ( hz - ( z * r - x * y ) );
}
}
/* k_sinf.c -- float version of k_sin.c
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_S1 = -1.6666667163e-01f, /* 0xbe2aaaab */
basicmath_S2 = 8.3333337680e-03f, /* 0x3c088889 */
basicmath_S3 = -1.9841270114e-04f, /* 0xb9500d01 */
basicmath_S4 = 2.7557314297e-06f, /* 0x3638ef1b */
basicmath_S5 = -2.5050759689e-08f, /* 0xb2d72f34 */
basicmath_S6 = 1.5896910177e-10f; /* 0x2f2ec9d3 */
float basicmath___kernel_sinf( float x, float y, int iy )
{
float z, r, v;
int32_t ix;
GET_FLOAT_WORD( ix, x );
ix &= 0x7fffffff; /* high word of x */
if ( ix < 0x32000000 ) { /* |x| < 2**-27 */
if ( ( int )x == 0 ) return x; /* generate inexact */
}
z = x * x;
v = z * x;
r = basicmath_S2 + z * ( basicmath_S3 + z * ( basicmath_S4 + z *
( basicmath_S5 + z * basicmath_S6 ) ) );
if ( iy == 0 ) return x + v * ( basicmath_S1 + z * r );
else return x - ( ( z * ( basicmath_half * y - v * r ) - y ) - v *
basicmath_S1 );
}
/* s_copysignf.c -- float version of s_copysign.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
copysignf(float x, float y)
copysignf(x,y) returns a value with the magnitude of x and
with the sign bit of y.
*/
float basicmath___copysignf( float x, float y )
{
u_int32_t ix, iy;
GET_FLOAT_WORD( ix, x );
GET_FLOAT_WORD( iy, y );
SET_FLOAT_WORD( x, ( ix & 0x7fffffff ) | ( iy & 0x80000000 ) );
return x;
}
/* s_cosf.c -- float version of s_cos.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
float basicmath___cosf( float x )
{
float y[ 2 ], z = 0.0f;
int32_t n, ix;
GET_FLOAT_WORD( ix, x );
/* |x| ~< pi/4 */
ix &= 0x7fffffff;
if ( ix <= 0x3f490fd8 ) return basicmath___kernel_cosf( x, z );
/* cos(Inf or NaN) is NaN */
else
if ( ix >= 0x7f800000 ) return x - x;
/* argument reduction needed */
else {
n = basicmath___ieee754_rem_pio2f( x, y );
switch ( n & 3 ) {
case 0:
return basicmath___kernel_cosf( y[ 0 ], y[ 1 ] );
case 1:
return -basicmath___kernel_sinf( y[ 0 ], y[ 1 ], 1 );
case 2:
return -basicmath___kernel_cosf( y[ 0 ], y[ 1 ] );
default:
return basicmath___kernel_sinf( y[ 0 ], y[ 1 ], 1 );
}
}
}
/* s_fabsf.c -- float version of s_fabs.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
/*
fabsf(x) returns the absolute value of x.
*/
float basicmath___fabsf( float x )
{
u_int32_t ix;
GET_FLOAT_WORD( ix, x );
SET_FLOAT_WORD( x, ix & 0x7fffffff );
return x;
}
/*
isinff(x) returns 1 if x is inf, -1 if x is -inf, else 0;
no branching!
*/
int basicmath___isinff ( float x )
{
int32_t ix, t;
GET_FLOAT_WORD( ix, x );
t = ix & 0x7fffffff;
t ^= 0x7f800000;
t |= -t;
return ~( t >> 31 ) & ( ix >> 30 );
}
/* s_scalbnf.c -- float version of s_scalbn.c.
Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com.
*/
static const float basicmath_two25 = 3.355443200e+07f, /* 0x4c000000 */
basicmath_twom25 = 2.9802322388e-08f; /* 0x33000000 */
float basicmath___scalbnf ( float x, int n )
{
int32_t k, ix;
GET_FLOAT_WORD( ix, x );
k = ( ix & 0x7f800000 ) >> 23; /* extract exponent */
if ( k == 0 ) { /* 0 or subnormal x */
if ( ( ix & 0x7fffffff ) == 0 ) return x; /* +-0 */
x *= basicmath_two25;
GET_FLOAT_WORD( ix, x );
k = ( ( ix & 0x7f800000 ) >> 23 ) - 25;
}
if ( k == 0xff ) return x + x; /* NaN or Inf */
k = k + n;
if ( n > 50000 || k > 0xfe )
return basicmath_huge * basicmath___copysignf( basicmath_huge,
x ); /* overflow */
if ( n < -50000 )
return basicmath_tiny * basicmath___copysignf( basicmath_tiny,
x ); /*underflow*/
if ( k > 0 ) { /* normal result */
SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) );
return x;
}
if ( k <= -25 )
return basicmath_tiny * basicmath___copysignf( basicmath_tiny,
x ); /*underflow*/
k += 25; /* subnormal result */
SET_FLOAT_WORD( x, ( ix & 0x807fffff ) | ( k << 23 ) );
return x * basicmath_twom25;
}

View File

@ -0,0 +1,61 @@
/*
====================================================
Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.
Developed at SunPro, a Sun Microsystems, Inc. business.
Permission to use, copy, modify, and distribute this
software is freely granted, provided that this notice
is preserved.
====================================================
*/
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: wcclibm.h
Author: Unknown
Function: IEEE754 software library routines.
Source: Sun Microsystems
Original name: wcclibm.h
Changes: No major functional changes.
License: See the terms above.
*/
#ifndef _WCCLIBM
#define _WCCLIBM
#define int32_t int
#define u_int32_t unsigned int
// Often used variables/consts
static const float basicmath_one = 1.0f,
basicmath_tiny = 1.0e-30f,
basicmath_half = 5.0000000000e-01, /* 0x3f000000 */
basicmath_huge = 1.0e30,
basicmath_two = 2.0,
basicmath_two24 = 16777216.0, /* 0x4b800000 */
basicmath_zero = 0.0;
float basicmath___copysignf( float x, float y );
float basicmath___cosf( float x );
float basicmath___fabsf( float x );
float basicmath___ieee754_acosf( float x );
float basicmath___ieee754_powf( float x, float y );
int32_t basicmath___ieee754_rem_pio2f( float x, float *y );
float basicmath___ieee754_sqrtf( float x );
int basicmath___isinff ( float x );
float basicmath___kernel_cosf( float x, float y );
float basicmath___kernel_sinf( float x, float y, int iy );
float basicmath___scalbnf ( float x, int n );
#endif // _WCCLIBM

View File

@ -0,0 +1,25 @@
# ~~~
# SPDX-License-Identifier: MIT
# SPDX-FileCopyrightText: 2026, Friedrich-Alexander-Universität Erlangen-Nürnberg (FAU)
# ~~~
cmake_minimum_required(VERSION 3.20)
project(deg2rad)
set(TACLEBENCH_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../..")
set(REPOSITORY_ROOT_PATH "${CMAKE_CURRENT_LIST_DIR}/../../../..")
set(APP_TARGET_NAME "${CMAKE_PROJECT_NAME}")
if(DEFINED TACLEBENCH_VARIANT AND "${TACLEBENCH_VARIANT}" STREQUAL "inline")
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/inline/deg2rad.c")
else()
set(APP_SOURCE_FILE_PATH
"generated/modified_sources/default/deg2rad.c")
endif()
include(${REPOSITORY_ROOT_PATH}/cmake/taclebench_wasm.cmake)

View File

@ -0,0 +1,78 @@
Original provenience: MiBench benchmark suite,
http://wwweb.eecs.umich.edu/mibench
2016-02-09:
- Added TACLeBench header
- Renamed benchmark from 'basicmath_small' to 'basicmath'
- Fixed a typo in code comments: 'soem' -> 'some'
- Removed unused variable 'n' from the main funcion
- Added variable 'double Y' to the main function and accumulated the results of
'deg2rad(X)' and 'rad2deg(X)' in this variable so that the compiler warning
'statement with no effect' is fixed.
- Removed conditionally compiled main (test) function from isqrt.c
- Removed conditionally compiled main (test) function from cubic.c
- Removed commented-out code
- Removed unused function, variable, macro and type declarations, structs and
unions
- Removed seemingly unnecessary empty lines
- Renamed memcpy.t to basicmath_libc.c
- Removed unused files:
rad2deg.c
sniptype.h
sniptype.h
- Created basicmath_libc.h and put declaration of basicmath_memcpy() in it
- Reorganized snipmath.h so that the following are in the given order just
after the header
- includes
- declarations of functions
- Reorganized sniptype.h so that the following are in the given order just
after the header
- macro definitions
- type definitions
- Removed duplicated copyright information from wcclibm.c
- Removed __STDC__ checks from wcclibm.c and used only ANSI style function
arguments
- Removed 'last modified' comments from files
- Removed mention 'use __kernel_rem_pio2f()' from comments of function
__ieee754_rem_pio2f() since it doesn't really use it.
- Removed math functions specialization macros from wcclibm.h and updated call
sites with explicit nameks of the functions.
- Removed '#define double float' from wcclibm.h and replaced all 'double's
with 'float's in the benchmark
- Added a new main function that calls the old main function
- Annotated basicmath_main() as the entry point of the analysis
- Applied code formatting according to the following rules
- Lines shall not be wider than 80 characters; whenever possible, appropriate
line breaks shall be inserted to keep lines below 80 characters
- Indentation is done using whitespaces only, no tabs. Code is indented by
two whitespaces
- Two empty lines are put between any two functions
- In non-empty lists or index expressions, opening '(' and '[' are followed by
one whitespace, closing ')' and ']' are preceded by one whitespace
- In comma- or colon-separated argument lists, one whitespace is put after
each comma/colon
- Names of functions and global variables all start with a benchmark-specific
prefix (here: statemate_) followed by lowercase letter
- For pointer types, one whitespace is put before the '*'
- Operators within expressions shall be preceded and followed by one
whitespace
- Code of then- and else-parts of if-then-else statements shall be put in
separate lines, not in the same lines as the if-condition or the keyword
"else"
- Opening braces '{' denoting the beginning of code for some if-else or loop
body shall be put at the end of the same line where the keywords "if",
"else", "for", "while" etc. occur
2017-06-27
- Introduce basicmath_init and basicmath_return functions.
- Add prefix basicmath_ to global variables.
- Introduce dummy initialization in ieee754_rem_pio2f to please linter.
2017-07-10
- Fix possible stack buffer overflow caused by sizeof of incorrect type.
2019-03-07
-split basicmath into seperate files
-Add TACLeBench Header
-put each benchmark into a seperate folder
-adjust the code formatting to the common TACLeBench code style

View File

@ -0,0 +1,90 @@
/*
This program is part of the TACLeBench benchmark suite.
Version V 1.9
Name: deg2rad
Author: unknown
Function: deg2rad performs conversion of degree to radiant
Source: MiBench
http://wwweb.eecs.umich.edu/mibench
Original name: basicmath_small
Changes: no major functional changes
License: this code is FREE with no restrictions
*/
#include "pi.h"
#define deg2rad(d) ((d)*PI/180)
/*
Forward declaration of functions
*/
void deg2rad_init( void );
void deg2rad_main( void );
int deg2rad_return( void );
int main( void );
/*
Declaration of global variables
*/
float deg2rad_X, deg2rad_Y;
/*
Initialization function
*/
void deg2rad_init( void )
{
deg2rad_X = 0;
deg2rad_Y = 0;
}
/*
Return function
*/
int deg2rad_return( void )
{
int temp = deg2rad_Y;
if ( temp == 1133 )
return 0;
else
return -1;
}
/*
Main functions
*/
void _Pragma( "entrypoint" ) deg2rad_main( void )
{
/* convert some rads to degrees */
_Pragma( "loopbound min 361 max 361" )
for ( deg2rad_X = 0.0f; deg2rad_X <= 360.0f; deg2rad_X += 1.0f )
deg2rad_Y += deg2rad( deg2rad_X );
}
int main( void )
{
deg2rad_init();
deg2rad_main();
return deg2rad_return();
}

Some files were not shown because too many files have changed in this diff Show More