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(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();
}